psycopg2嵌套事务出错:全部回滚还是仅回滚最后事务?
嵌套事务出错后的回滚规则
首先要明确:数据库的嵌套事务行为取决于具体数据库系统、事务实现方式以及应用层的事务配置,不同场景结果不同:
若使用数据库原生的模拟嵌套事务(如MySQL、PostgreSQL的
SAVEPOINT机制):- 若内层操作出错时,仅针对该内层设置的
SAVEPOINT执行回滚,那么只会撤销内层的操作,外层之前的未提交操作会保留; - 若未设置回滚点,或直接触发了整个事务的回滚指令,那么所有未提交的操作(包括内层和外层)都会被全部回滚。
- 若内层操作出错时,仅针对该内层设置的
若在应用层实现"事务嵌套"(比如代码中一个事务方法调用另一个事务方法):
- 若采用默认的事务传播策略(如Spring的
REQUIRED),内外层共用同一个事务,任何环节出错都会导致整个事务的所有操作回滚; - 若配置了独立的事务传播策略(如Spring的
REQUIRES_NEW),内层会开启全新事务,内层提交后即独立生效,外层出错不会影响已提交的内层,内层出错也仅回滚自身操作。
- 若采用默认的事务传播策略(如Spring的
少数支持真正嵌套事务的数据库(如Oracle的部分版本):
内层事务提交后就会永久生效,后续外层事务出错时,不会回滚已经提交的内层操作;若内层事务未提交就出错,仅回滚内层的未提交操作,外层事务可继续执行或选择回滚自身。
总结:不存在绝对的"全部回滚"或"仅回滚最后一个"的结论,核心要看数据库的事务支持特性、是否设置回滚点,以及应用层的事务传播配置。
内容的提问来源于stack exchange,提问作者Lucas Emanuel
相关产品推荐
相关产品推荐

