MySql 存储过程是原子的吗?

Hel*_*ele 5 mysql atomic

正如标题所说,MySQL 中的存储过程是原子的吗?即会像

for (..)
  <check_if_row_has_flag>
for (..)
  <update_row>
Run Code Online (Sandbox Code Playgroud)

原子地工作?

有趣的是,除了 2009 年的一个论坛帖子外,我在 Google 上找不到太多关于此的信息。

Bil*_*win 6

不,存储过程不是原子的。

您上面显示的伪代码具有竞争条件。第一个循环,检查一行是否有标志,将返回一个答案,但除非您执行锁定读取,否则另一个并发会话可能会在您的过程读取该行后立即更改标志。

这就是乐观锁的效果。在您发出锁定它们的语句之前,不会锁定行。所以即使在一个事务中,你也没有原子锁。

MySQL 支持的原子性是针对事务提交的。事务是原子的,因为在事务期间所做的所有更改都会成功,否则所有更改都会回滚。其他会话无法看到您处于部分完成状态的交易。


回复下面的评论:

您可以从您的应用程序调用事务中的过程:

START TRANSACTION;
CALL MyProcedure();
COMMIT;
Run Code Online (Sandbox Code Playgroud)

您甚至可以在过程主体中显式启动和提交事务(或多个串行事务):

CREATE PROCEDURE MyProcedure()
BEGIN
    START TRANSACTION;
    ...UPDATE, INSERT, DELETE, blah blah...
    COMMIT;
END 
Run Code Online (Sandbox Code Playgroud)

但过程本身并不隐式启动或提交事务。