我正在建立游戏会话,每个会话都有很多州。当游戏要求下一步时,选择当前游戏会话,然后选择最新游戏状态。用户对状态进行操作,返回状态,对照最后状态进行检查,如果有效,则保存操作,创建新状态,并将其返回给用户。这个过程重复。在游戏结束时,游戏会话被标记为已结束,并且会创建一个新会话。
如果同时提交两次动作,他们将能够抓住同一个游戏会话,获取最新的游戏状态并根据动作进行验证。该事务似乎只是阻止了在事务中修改的任何行的写入。无论哪一个被击中第二个将等到第一个完成,然后写下它的数据并创建下一个游戏状态。
我需要在游戏会话行上创建一个读锁定,因此如果任何实例在某些事务中对游戏会话状态执行任何操作,则任何其他尝试读取游戏会话的操作将被延迟,直到该实例/事务具有已完成,因此读取将始终在事务后获取数据。
我还没有找到如何创建行读锁定的方法。有人可以帮我吗?感谢。
编辑:
我想我需要在事务中做一个SELECT游戏会话行FOR UPDATE,这会锁定行进行读取,但是在事务发生之前我会有一个SELECT游戏会话行LOCK IN SHARE MODE来确保它等到它可以启动它?
不确定我是否正确使用它们。
在我用PHP PDO(特别是Eloquent)抽象的PHP代码中的某处:
SELECT FROM game_session WHERE id = 5 LOCK IN SHARE MODE; #wait till any lock is completed
BEGIN TRANSACTION;
SELECT FROM game_session WHERE id = 5 FOR UPDATE; #lock the row
/* stuff */
END TRANSACTION;
这似乎有点多余。我知道事务隔离级别也有很多,虽然我不清楚它将在哪里配合,是否需要SERIALIZABLE?或者这会弄乱" FOR UPDATE"位?