????默认情况下,事务只有遇到运行期异常(RuntimeExcertion的子类)以及 Error 时才会回滚,在遇到检查型(Checked Exception)异常时不会回滚。像 1/0,空指针这些是RuntimeException,而IOException 则算是 Checked Exception,换言之,默认情况下,如果发生IOException并不会导致事务回滚。如果我们希望发生IOException时也能触发事务回滚,那么可以按照如下方式配置:
@Transactional(rollbackFor = I0Exception.class)
public void handle2() {
jdbcTemplate.update();
accountService.handle1();
}
rollback-for="java.io.IOException"
<!--配置事务的通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置事务的属性,name 表示哪些方法需要添加事务,可以使用通配符-->
<tx:method name="transfer*" isolation="SERIALIZABLE" propagation="REQUIRED"
rollback-for="java.io.IOException"/>
<tx:method name="add*" isolation="SERIALIZABLE" propagation="REQUIRED" rollback-for="java.io.IOException"/>
<tx:method name="delete*" isolation="SERIALIZABLE" propagation="REQUIRED" rollback-for="java.io.IOException"/>
</tx:attributes>
</tx:advice>
还可以发生某些异常不回滚则:
java方式
rollbackFor 换成 noRollbackFor
xml类似。。。
????只读事务一般设置在查询方法上,但不是所有的查询方法仍需要只读事务,要看具体情况。
????一般来说,如果这个业务方法只有一个查询SQL,那么就没必要添加事务,强行添加最终效果适得其反。但是如果一个业务方法中有多个查询SQL,情况就不一样了:多个查询SQL,默认情况下,每个查询 SQL 都会开启一个独立的事务,这样,如果有并发操作修改了数据,那么多个查询 SQL 就会查到不一样的数据。此时,如果我们开启事务,并设置为只读事务,那么多个查询SQL将被置于同一个事务中,多条相同的 SQL 在该事务中执行将会获取到相同的查询结果。设置事务只读的方式如下: Java 配置:
Transactional(readOnly = true)
read-only="true"
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置事务的属性,name 表示哪些方法需要添加事务,可以使用通配符-->
<tx:method name="transfer*" isolation="SERIALIZABLE" propagation="REQUIRED"
rollback-for="java.io.IOException"
read-only="true"/>
</tx:attributes>
</tx:advice>
????超时时间是说一个事务允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。事务超时时间配置方式如下(单位为秒)
@Transactional(timeout =10)
timeout="10"
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置事务的属性,name 表示哪些方法需要添加事务,可以使用通配符-->
<tx:method name="transfer*" isolation="SERIALIZABLE" propagation="REQUIRED"
rollback-for="java.io.IOException"
read-only="true"
timeout="10"/>
</tx:attributes>
</tx:advice>
在TransactionDefinition中以int的值来表示超时时间,其单位是秒,默认值为-1。
主要有这样几种情况
异常被catch捕获了
方法非public
非运行时异常(只有配置了才会事务生效)
数据库不支持事务
数据库不支持事务,spring咋配置都没有用
不是spring bean
声明式事务主要是通过动态代理来处理事务的,如果你拿到手的UserService对象就是原原本本的UserService(如果自己new了一个UserService就是这种情况),那么事务代码在哪里?没有事务处理的代码,事务自然不会生效。
声明式事务的核心,就是动态代理生成的那个对象,没有用到那个对象,事务就没戏。