场景描述:
由于业务需求,要在定时任务中做数据统计,任务执行清空表,然后将聚合数据重新插入数据库的操作。
技术背景:
1.springboot中开启shedule
2.controller中加Transactional注解
3.service中加Transactional注解
遇到问题:
1.事务没有生效
2.数据没有回滚
(额,第一个问题是try catch了异常,看似没有生效实际是生效的。不讲了,略过… 狗头.jpg)
情形1:
在controller中加事务,service也加事务,比较truncate和delete
truncate执行:
结果显示事务没有生效(原因看最后解释)。
delete执行
开始执行之前数据库数据如下:
执行delete
执行delete后数据库
这里可以看到数据库事务没有提交。
抛出异常
抛出异常后看一下数据库数据,依然没变。
结果显示事务生效,满足需求。
情形2,在controller中加事务,service不加事务
执行delete操作
此时数据库数据没变:
执行完毕后数据库也是如此,不再赘述,复合预期。
truncate操作同情形1的相同,也是不生效。
情形3,在service中加事务,service执行业务操作
controller代码如下
这里也是模拟了truncate和delete的操作,结果同controller中加事务并无不同,都是:
deleteTable执行了事务回滚,truncateTable没有回滚。
解释:
delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效。如果有相应的 trigger,执行的时候将被触发。
truncate、drop 是数据库定义语言(ddl),操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。