Spring事务回滚规则,是否只读,超时时间,事务失效

本文介绍了Spring框架中的事务管理,包括默认的回滚规则、如何配置事务以在IOException等异常时回滚,只读事务的应用场景,以及超时时间和事务失效的情况。强调了声明式事务通过动态代理实现的核心机制。
摘要由CSDN通过智能技术生成

一:回滚规则

    默认情况下,事务只有遇到运行期异常(RuntimeExcertion的子类)以及 Error 时才会回滚,在遇到检查型(Checked Exception)异常时不会回滚。像 1/0,空指针这些是RuntimeException,而IOException 则算是 Checked Exception,换言之,默认情况下,如果发生IOException并不会导致事务回滚。如果我们希望发生IOException时也能触发事务回滚,那么可以按照如下方式配置:

java配置:

@Transactional(rollbackFor = I0Exception.class)
    public void handle2() {
      jdbcTemplate.update();
      accountService.handle1();
}

xml配置:

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 配置:

Java配置

Transactional(readOnly = true)

xml配置

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>

三:超时时间

    超时时间是说一个事务允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。事务超时时间配置方式如下(单位为秒)

Java 配置:

@Transactional(timeout =10)

xml配置

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就是这种情况),那么事务代码在哪里?没有事务处理的代码,事务自然不会生效。

声明式事务的核心,就是动态代理生成的那个对象,没有用到那个对象,事务就没戏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值