개발중인 게임에서 경쟁 조건을 피하기 위해 Django 1.6 트랜잭션을 사용하려고합니다. 게임 서버는 2 명의 플레이어를 짝 지어주는 하나의 간단한 목표를 가지고 있습니다.Django 1.6 트랜잭션이 경쟁 조건을 피하기 위해
내 현재의 접근 방식은 다음과 같습니다
- 사용자는 게임을 기다리는 다른 사람이있는 경우
- 서버 점검을 놀고 싶어.
- 이이 아닌 경우 GameConnection 개체 (고유 식별자 -uuid4)가 생성됩니다.
- 이이면 GameConnection 식별자를 가져와 GameConnection을 삭제합니다.
# data['nickname'] = user's choice games = GameConnection.objects.all() if not games: game = GameConnection.objects.create(connection=unicode(uuid.uuid4())) game.nick1 = data["nickname"] game.save() response = HttpResponse(json.dumps({'connectionId': game.connection, 'whoAmI': 1, 'nick1': game.nick1, 'nick2': ""})) else: game = games[0] conn = game.connection nick1 = game.nick1 nick2 = data["nickname"] game.delete() response = HttpResponse(json.dumps({'connectionId': conn, 'whoAmI': 2, 'nick1': nick1, 'nick2': nick2})) return response
은 물론 위의 코드에서 경쟁 조건이 있습니다 :
이는 코드입니다. 이 코드는 원 자성이 아니므로 다음과 같이 발생할 수 있습니다.
- 게임 연결을 확인합니다. 찾지 못합니다.
- A 게임 연결을 만듭니다.
- B 게임 연결을 확인합니다. 하나 (A)를 찾습니다.
- C 게임 연결을 확인합니다. 하나 (A)를 찾습니다.
- B는 A의 연결 식별자를 가져와 게임을 시작합니다.
- C가 A의 연결 식별자를 가져와 게임을 시작합니다.
나는이 전체 블록을 with transaction.atomic():
아래에서 시도했거나 @transaction.atomic
데코레이터를 사용했습니다. 하지만 여전히 경쟁 조건을 재현 할 수 있습니다.
여기에 누락 된 트랜잭션 동역학에 대한 정보가있을 것입니다. 누구든지 빛을 흘릴 수 있습니까?
저는 전문가는 아니지만 제 이해에 따라 원자 트랜잭션이 쓰기에 적용됩니다. 귀하의 경우에는 한 번에 한 쌍의 페어링 만 발생하도록하기 위해 일종의 뮤텍스 잠금을 사용하려고 할 수 있습니다. 이것은 Java에서 @synchronized와 유사합니다. 그래도 모든 성능면에서 효율적이지는 않습니다. –