Tôi đang cố gắng sử dụng các giao dịch Django 1.6 để tránh điều kiện chạy đua trên một trò chơi mà tôi đang phát triển. Máy chủ trò chơi có một mục tiêu đơn giản: để ghép nối hai người chơi.Giao dịch Django 1.6 để tránh điều kiện đua xe
cách tiếp cận hiện tại của tôi là:
- Người dùng muốn chơi
- sẽ kiểm tra máy chủ nếu có bất cứ ai khác chờ đợi để chơi.
- Nếu có không, nó tạo ra một đối tượng GameConnection (mà có một định danh duy nhất - uuid4).
- Nếu có là, số nhận dạng GameConnection và xóa GameConnection.
Đây là mã:
# 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
Rõ ràng có một điều kiện chủng tộc trên các mã trên. Vì mã này không phải là nguyên tử, có thể xảy ra rằng:
- Kiểm tra kết nối trò chơi. Không tìm thấy.
- A tạo kết nối trò chơi.
- B kiểm tra kết nối trò chơi. Tìm một (A).
- C kiểm tra kết nối trò chơi. Tìm một (A).
- B nhận mã nhận dạng kết nối của A và bắt đầu trò chơi.
- C nhận mã nhận dạng kết nối của A và bắt đầu trò chơi.
Tôi đã cố gắng thực hiện nhưng toàn bộ khối này dưới with transaction.atomic():
hoặc sử dụng trang trí @transaction.atomic
. Nhưng vẫn còn, tôi có thể tái tạo điều kiện chủng tộc.
Tôi chắc chắn có điều gì đó về động lực giao dịch mà tôi thiếu ở đây. Ai có thể làm sáng tỏ không?
Tôi không phải là chuyên gia, nhưng theo sự hiểu biết của tôi, các giao dịch nguyên tử được áp dụng để ghi. Trong trường hợp của bạn, bạn có thể muốn sử dụng một số loại khóa mutex để đảm bảo chỉ có một cặp xảy ra tại một thời điểm. Điều này tương tự như @synchronized trong Java. Không hiệu quả ở tất cả các hiệu suất khôn ngoan mặc dù. –