2023_08—第三周

2023-08-23

最近在 Review 同事代码时发现某个方法中加了事务 @Transactional 注解,方法体中的逻辑大概是这样:👇🏻

1
2
3
4
5
6
7
@Transactional
public void test(){
aMapper.deleteAll();
for(*;*;*){
aMapper.insert();
}
}

看上去挺正常的,但实际进入 deleteAll() 方法后发现 SQL 使用的是 TRUNCATE TABLE Statement,这就有意思了。这种情况事务能不能生效呢?如果不生效就悲催了,一旦 insert() 方法执行异常,整张表就相当于被清空了。。

查资料先,,

首先,TRUNCATE TABLE Statement 是 DDL[^1]。

其次,在 Mysql 官网中,有这样一章专门用来描述事务不能回滚的情况[^2]:

Some statements cannot be rolled back. In general, these include data definition language (DDL) statements, such as those that create or drop databases, those that create, drop, or alter tables or stored routines.

You should design your transactions not to include such statements. If you issue a statement early in a transaction that cannot be rolled back, and then another statement later fails, the full effect of the transaction cannot be rolled back in such cases by issuing a ROLLBACK statement.


[^1]: 13.1.34 TRUNCATE TABLE Statement
[^2]: 13.3.2 Statements That Cannot Be Rolled Back