假设我有两台服务器同时使用InnoDB在MySQL 5.5数据库上启动事务。 两个事务都做同样的事情:读取一行,然后根据其内容更新行。 我想确保这两个交易一个接一个地运行。 也就是说, 第二个事务不应该被允许在第一个事务完成之前读取该行。 理想情况下,这意味着第二个事务中的SELECT语句将等到第一个事务被提交,然后返回更新后的值。
这可能吗? 如果没有,是否有一个比MySQL更适合这个任务的数据库?
如果是这样,一个相关的问题:假设第一台服务器中间事务崩溃,所以没有收到任何COMMIT消息。 如何设置一个超时后交易将自动回滚,以便第二个交易不会永久延迟? ( 更新 :我把这个作为一个单独的问题 。
SELECT ... FOR UPDATE可能会满足您的需求。 看这里。
好的,我把Shane的build议转化为一个testing用例。 我有一个名为nsync的表,id为1 ,值为foo 。 然后我运行这个事务:
START TRANSACTION; SELECT * FROM nsync WHERE id = '1' FOR UPDATE; SELECT SLEEP(10); UPDATE nsync SET stringy = 'bar' WHERE id = '1'; COMMIT;
并在睡眠间隔期间跑步
SELECT * FROM nsync WHERE id = '1' FOR UPDATE;
有用! SELECT等待,直到第一个事务完成,并返回更新的值bar 。
请注意,这两个 SELECT语句使用FOR UPDATE是很重要的; 如果第一个SELECT没有使用它,那么这行不会被locking。 如果第二个SELECT没有使用它,它不会在乎锁。