开发者社区 问答 正文

Mysql事务里面的程序

在mysql过程中,我希望一个事务是非自动提交的,而另一个则没有自动提交。

基本上它在过程事务内部创建了一个不同的事务块。

Create procedure sampleProc() 
Begin    

call procedure abc()       // this to commit only when all is committed

insert into timetaken(some time);  //this to reflect immediately in DB.

call procedure abc()

insert into timetaken(some time);

...
these both can repeat n times

end;

展开
收起
垚tutu 2019-11-28 19:06:51 620 分享 版权
阿里云 AI 助理回答

要在MySQL过程中实现您描述的事务控制,即一个事务块是非自动提交的,而另一个事务内的操作需要立即反映到数据库中,可以通过在存储过程内部精细控制autocommit设置和显式使用START TRANSACTIONCOMMITROLLBACK来实现。以下是一个根据您的需求调整后的示例存储过程:

DELIMITER $$

CREATE PROCEDURE sampleProc()
BEGIN
    -- 开启第一个事务,此部分默认为非自动提交(autocommit默认为0)
    START TRANSACTION;

    CALL procedureABC();  -- 这个调用将不会立即提交,直到事务结束

    -- 如果procedureABC或之后的操作失败,可以在这里捕获异常并回滚事务
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;  -- 发生错误时回滚事务
        RESIGNAL;  -- 重新抛出信号以便上层处理
    END;

    -- 在这里插入数据,但为了满足立即反映到数据库的需求,
    -- 需要暂时开启自动提交,执行完后再恢复原状
    SET autocommit = 1;
    INSERT INTO timetaken(some_column) VALUES (CURRENT_TIMESTAMP);
    SET autocommit = 0;  -- 恢复非自动提交状态

    CALL procedureABC();  -- 再次调用,依然在未提交的事务中

    INSERT INTO timetaken(some_column) VALUES (CURRENT_TIMESTAMP);

    -- 所有操作成功后,提交整个事务
    COMMIT;
END$$

DELIMITER ;

关键点说明:

  • 使用START TRANSACTION明确开始一个事务,此时MySQL默认处于非自动提交模式。
  • 第一次调用procedureABC()时,其内发生的更改不会立即提交。
  • 通过临时将autocommit设置为1,确保INSERT INTO timetaken操作能立即生效并被持久化,然后立即将autocommit恢复为0,继续在事务中执行后续操作。
  • 定义了一个异常处理器,用于在procedureABC调用或其他操作失败时回滚事务,保证数据一致性。
  • 最终,在所有预期的操作都成功完成后,使用COMMIT提交事务,使得procedureABC所做的更改也得以保存。

请注意,频繁切换autocommit设置可能对性能有一定影响,且这种设计模式较为特殊,需谨慎考虑事务边界和数据一致性问题。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答