假设我有两台服务器同时使用 InnoDB 在 MySQL 5.5 数据库上启动事务。两个事务都执行相同的操作:读取一行,然后根据其内容更新该行。我希望确保两个事务一个接一个地运行。也就是说,在第一个事务完成之前,第二个事务不应该被允许读取该行。理想情况下,这意味着SELECT
第二个事务中的语句将等到第一个事务提交后,然后返回更新的值。
这可能吗?如果不可能,有没有比 MySQL 更适合这项任务的数据库?
如果是这样,那么一个相关的问题是:假设第一台服务器在事务中途崩溃,因此没有COMMIT
收到任何消息。我该如何设置超时,在此之后事务将自动回滚,以便第二笔事务不会永远被延迟?(更新:我把它拆分成单独问题。
答案1
SELECT ... FOR UPDATE
可能会满足您的需求。 看这里。
答案2
好的,我采纳了 Shane 的建议并将其变成了一个测试用例。我有一个名为的表,nsync
其中有一行,其中包含 id1
和 value 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
没有使用它,那么该行就不会被锁定;如果第二个SELECT
没有使用它,它就不会关心锁。