我正在尝试使用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
装饰器.但是,我仍然可以重现竞争条件.
我相信我在这里缺少一些交易动态.任何人都可以光明吗?