MySQL - 由两个并发进程一致地选择和更新

时间:2012-08-25 15:23:28

标签: mysql

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

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

现在有两个流程( Proc1 Proc2 )需要为同一用户的表note插入行。

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

两个流程( Proc1 Proc2 )是否有可能在其交易中检索相同的number(比如第一个流程)会在第二个流程执行SELECTINSERT语句之前执行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. Proc1:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
  4. Proc2:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
  5. Proc1:UPDATE note SET next_number = 6 WHERE number = 5
  6. Proc2:UPDATE note SET next_number = 6 WHERE number = 5
  7. Proc1:提交Proc1的交易
  8. Proc2:提交Proc2的交易
  9. 如果有可能,如何避免这种情况? SELECT ... FOR UPDATE会解决问题吗?

    更新 - 简化我的问题

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

1 个答案:

答案 0 :(得分:0)

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