在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;
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
要在MySQL过程中实现您描述的事务控制,即一个事务块是非自动提交的,而另一个事务内的操作需要立即反映到数据库中,可以通过在存储过程内部精细控制autocommit
设置和显式使用START TRANSACTION
、COMMIT
及ROLLBACK
来实现。以下是一个根据您的需求调整后的示例存储过程:
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
设置可能对性能有一定影响,且这种设计模式较为特殊,需谨慎考虑事务边界和数据一致性问题。