1

我有一个程序任务来执行表的一致更新。为简单起见,我将讨论虚拟表只是为了展示这个想法。所以我有两张桌子:usernote

note一个id(主键自动增量)和user_id(外键),numbernext_number
number是一些用户的注释。如果这是最新的用户注释,则next_number可以0等于或等于下一个用户注释的数量(如指向 C++ 链表中下一个节点的指针)。
所以每个用户都有从 1 到 n 编号的笔记。

现在一些两个进程(Proc1Proc2)需要将行插入到note同一用户的表中。

因此,每个进程都在启动一个事务,检索number最新用户的注释,然后执行一些其他操作并插入number递增到 1 的新行。

两个进程(Proc1Proc2)是否有可能在它们的事务中检索相同number的内容(比如第一个进程将SELECT在第二个进程执行其INSERTand语句之前执行UPDATE语句)?

例如:

  1. Proc1: SELECT number FROM note WHERE user_id = 1 AND next_number = 0- 检索到的数字5
  2. Proc2: SELECT number FROM note WHERE user_id = 1 AND next_number = 0- 检索到的数字5
  3. 过程1:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
  4. 过程2:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
  5. 过程1:UPDATE note SET next_number = 6 WHERE number = 5
  6. 过程2:UPDATE note SET next_number = 6 WHERE number = 5
  7. Proc1:提交Proc1的事务
  8. Proc2:提交Proc2的事务

如果可能,如何避免这种情况?会SELECT ... FOR UPDATE解决问题吗?

更新 - 简化我的问题

所以一般的问题是如果进程启动了一个事务,如何禁止其他 MySQL 会话与当前事务正在处理的行进行交互?

4

1 回答 1

0

您应该对此进行测试以确保它正在做正确的事情,但第二个SELECT ... LOCK IN SHARE MODE语句应该阻塞,直到第一个语句完成。您还应该查看隐式设置的 SERIALIZABLE 事务隔离级别。

于 2012-08-25T15:30:34.317 回答