DDL操作是否提交前置DML操作?三类事务场景问询
核心问题:DDL操作是否会提交之前执行的DML操作?
在绝大多数关系型数据库(如MySQL、Oracle、PostgreSQL)中,DDL操作会隐式提交当前未完成的事务——也就是说,执行DDL前的所有未提交DML操作都会被自动持久化到数据库,无法再通过rollback回滚。
先明确本次的具体执行步骤:
- 执行
Insert into tableA(未提交)
- 执行
- 执行
Drop tableB(DDL操作)
- 执行
- 执行
Insert into tableC
- 执行
场景A:完成三步操作后执行rollback,是否会回滚步骤1的操作?
不会。步骤2的Drop tableB是DDL操作,执行时已经隐式提交了步骤1的Insert into tableA,这部分数据已经永久写入数据库。后续执行rollback,只能回滚步骤3中未提交的Insert into tableC(如果步骤3没有被其他操作提交的话)。
场景B:上述步骤包含在存储过程D中,执行步骤3时发生错误,步骤1的操作是否已提交?
是的,已经提交。存储过程执行到步骤2的DDL时,就自动提交了步骤1的DML操作,和后续步骤3是否出错没有关系。步骤3的错误只会导致自身操作回滚(除非存储过程有特殊的错误处理逻辑),但步骤1的操作已经被DDL提交,无法撤销。
场景C:从事务角度看,执行步骤3时杀死会话与执行步骤3时发生错误有何区别?
- 发生错误时:如果是语句级错误,只会回滚当前步骤3的
Insert into tableC,步骤1的操作因为已经被DDL提交不受影响,步骤2的DDL操作本身是原子性的,已经完成且不可回滚。如果存储过程有显式事务逻辑,DDL依然会打断事务并提交之前的操作,错误仅影响当前出错语句,存储过程可能还会执行后续的错误处理代码。 - 杀死会话时:当前未完成的步骤3操作会被强制回滚,但步骤1的操作已经被DDL隐式提交,依然保留;步骤2的DDL操作也已完成,不会被回滚。和错误场景的核心区别是:杀死会话会直接终止整个会话的所有后续操作,没有机会执行存储过程的错误处理逻辑,但两者对步骤1、步骤2的最终结果没有差异。
内容的提问来源于stack exchange,提问作者StanSmith
相关产品推荐
相关产品推荐

