Spring事务的总结

事务的特性

一个事务必须要确保它的原子性,一致性,隔离性,持久性

  1. 原子性:一个事务,相当于客户下单需要新建一张订单然后保存到数据库中,新建订单就是一个事务,要么整个订单正确保存完成,要么完全不保存。
  2. 一致性:一旦这张订单完成后,无论是否成功,整个业务的流程对于这张订单的状态都是一致的,不会一部分下单成功,一部分下单失败。
  3. 隔离性:当很多的用户都要下单的时候,每个用户的订单之间要互相不干扰,隔离开来。
  4. 持久性:订单完成后,就把订单保存到持久化存储器中(数据库),就不会因为系统错误导致订单发生错误。

开启Spring事务有两种方式

编程式事务管理声明式事务管理

  1. 编程式事务管理:可以用TransactionTemplate工具类,它可以用在代码块中,控制事务的范围,如图1
  2. 声明式事务管理:声明式事务管理是建立在springAOP上的,在方法前和方法后进行拦截,可以通过注解的方式将开启一个事务,如图2

图一:↓

    //先声明transactionTemplate
    @Autowired
    private TransactionTemplate transactionTemplate;

    //方法中的代码块,TransactionTemplate工具类可以控制细粒度事务
    transactionTemplate.execute(new TransactionCallback() {

            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {
            //执行订单保存,更新,删除等操作如:xxx.updateByExample(这是调用Mybatis的dao层的接口,Mybatis会根据同名的XML中的配置信息创建一个代理类,动态代理,然后执行sql保存信息,完成事务)
              return Boolean.TRUE;
            }
        });

图2:↓

//订单的service实现类
@Service
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements OrderService{
    
    //以下是增加订单的方法,注解对于整个add方法进行事务管理,括号内就是如果有Exception返回,则对整个方法内的流程回滚,不进行任何修改
    //propagation 为事务传播机制(xxx可以按自身业务需求修改事务传播机制)
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.xxx)
    public boolean add(Order order, SySUser user) {
        //这里面是写的业务流程如,set订单号,订单价格,订单状态等
            
        //del()为内层事务
        del();


        return true;
    }


    //删除订单
    @Transactional(rollbackFor = Exception.class)
    public boolean del(Order order, SySUser user) {
        //这里面是写的业务流程如
        return true;
    }
    
}

事务的传播机制

事务的传播机制指的是在事务嵌套的场景中,比如一个事务方法里调用另一个事务方法(如:上面的add()方法是个事务,add方法里调用del()方法)。那么这两个方法是如何去提交呢,是分别单独提交还是一起提交,这就是事务传播机制来确定的。常用的事务传播机制如下:

  • PROPAGATION_REQUIRED: 这个是默认的事务传播机制,例子如上图,如果del()方法定义传播机制为PROPAGATION_REQUIRED,add()方法也开启了事务,然后add()方法中调用del()方法,那么add()方法为外层事务,del()方法为内层事务,那么add()方法就会启动事务,del()方法查看到自己在add()方法的事务中,就不会开启事务,这个时候只有一个add()方法的事务,两个方法共同用一个事务,无论哪个方法中抛出异常,都会导致两个方法一起回滚,或者一起成功
  • PROPAGATION_REQUES_NEW:还是例子如上图,如果del()方法定义传播机制为PROPAGATION_REQUIRED_NEW,add()方法也开启了事务,会先把add()的事务挂起(停止,先放一边),执行del()的事务,完成del()的事务后再执行add()的事务,如果add()也就是外层事务中有抛出异常,那么仅仅是add()方法进行回滚,不会影响到del()的事务,如果del()方法也就是内层事务抛出异常,那么add()和del()方法都要进行回滚,总的来说就是PROPAGATION_REQUIRED_NEW传播机制就是会开启一个新的事务,外层事务不会对内层事务产生影响,但是内层事务的异常会影响外层事务的回滚。
  • PROPAGATION_SUPPORT:例子如上图,如果add()方法开启事务,del()方法开启事务为PROPAGATION_SUPPORT,那么del()的事务就会加入add()的事务,如果add()没有开启事务,del()方法也用非事务方法执行,这里就有一个疑问,PROPAGATION_SUPPORT这个事务传播机制不就和不加 @Transactional一样吗?这个问题可以去搜一下如https://www.cnblogs.com/zhangliang88/p/12803356.html
  • PROPAGATION_NOT_SUPPORT:这个事务传播机制就如同名字一样,不支持事务,例子如上图,如果add()开启了事务,然后del()的事务传播机制为PROPAGATION_NOT_SUPPORT,那么在执行del()方法的时候,会吧add()挂起放一边,然后完成del()的业务流程,再回到add()中执行事务,无论add()中事务是成功失败,都不会影响del()的结果
  • PROPAGATION_NEVER:例子如上图,如果del()方法的事务传播机制为PROPAGATION_NEVER,那么如果它发现它的外层事务开启,那么就会直接抛出错误
  • PROPAGATION_MANDATORY:这个事务传播机制与PROPAGATION_NEVER相反,如果它发现它的外层没有事务开启,那么就会直接抛出错误。
  • PROPAGATION_NESTED:这个事务传播机制比较特殊,它是一个真正的嵌套事务,例子如上图,如果del()开启PROPAGATION_NESTED事务传播机制,而add()如果没有开启事务,则del()的传播机制按PROPAGATION_REQUIRED处理,如果add()开启了事务,那么del()就是add()的事务的子事务,和PROPAGATION_REQUES_NEW事务传播机制(这个事务传播机制,内层事务会开启新的事务)产生了区别,PROPAGATION_NESTED事务传播机制则是依赖于外层事务,外层事务提交,子事务才会提交,回滚也是一样的。可以参考https://blog.csdn.net/yanxin1213/article/details/100582643

事务的隔离级别

事务隔离级别,就是根据不同的业务需求和环境,规定不同事务之间的影响程度,在并发的环境下,当多个事务需要对同一个数据进行操作时,不同的级别会导致不同的影响,完全的隔离就相当于一个事务一个事务的去操作数据,这会影响程序性能,而不完全隔离又会造成脏读,不可重复度和幻读。

  1. 脏读:脏读发生在一个事务读取了被另一个事务改写但尚未提交的数据时。如果这些改变在稍后被回滚了,那么第一个事务读取的数据就会是无效的。
  2. 不可重复读:不可重复读发生在一个事务执行相同的查询两次或两次以上,但每次查询结果都不相同时。这通常是由于另一个并发事务在两次查询之间更新了数据。
  3. 幻读:幻读和不可重复读相似。当一个事务(T1)需要写入一条数据,写入前判断id是否存在,不存在才写入,但是当T1差询到id不存在,但还没写入的时候,另一个并发事务(T2)插入了一条记录,id就是T1判断的id的值,那么T1插入数据就会报错相同的id冲突看了,幻读就发生了。

Spring事务隔离级别有四种:

  • ISOLATION_DEFAULT:使用后端数据库默认的隔离级别。
  • ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据,这种隔离级别会产生脏读,不可重复读和幻读。
  • ISOLATION_READ_COMMITTED:允许从已经提交的并发事务读取。可防止脏读,但幻读和不可重复读仍可能会发生。
  • ISOLATION_REPEATABLE_READ:对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻读仍可能发生。
  • ISOLATION_SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。

以上内容为自己查,然后按自己的理解写的

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值