我有一个程序任务来执行表的一致更新。为简单起见,我将讨论虚拟表只是为了展示这个想法。所以我有两张桌子:user
和note
。
有note
一个id
(主键自动增量)和user_id
(外键),number
和next_number
。
这number
是一些用户的注释。如果这是最新的用户注释,则next_number
可以0
等于或等于下一个用户注释的数量(如指向 C++ 链表中下一个节点的指针)。
所以每个用户都有从 1 到 n 编号的笔记。
现在一些两个进程(Proc1和Proc2)需要将行插入到note
同一用户的表中。
因此,每个进程都在启动一个事务,检索number
最新用户的注释,然后执行一些其他操作并插入number
递增到 1 的新行。
两个进程(Proc1和Proc2)是否有可能在它们的事务中检索相同number
的内容(比如第一个进程将SELECT
在第二个进程执行其INSERT
and语句之前执行UPDATE
语句)?
例如:
- Proc1:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 检索到的数字5 - Proc2:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 检索到的数字5 - 过程1:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
- 过程2:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
- 过程1:
UPDATE note SET next_number = 6 WHERE number = 5
- 过程2:
UPDATE note SET next_number = 6 WHERE number = 5
- Proc1:提交Proc1的事务
- Proc2:提交Proc2的事务
如果可能,如何避免这种情况?会SELECT ... FOR UPDATE
解决问题吗?
更新 - 简化我的问题
所以一般的问题是如果进程启动了一个事务,如何禁止其他 MySQL 会话与当前事务正在处理的行进行交互?