Administrator
Administrator
Published on 2025-01-06 / 0 Visits
0
0

Springboot(2.7.6)单体工程-事务管理(E)

事务是一个逻辑的工作单元,在这个工作单元中,如果存在有多个dml语句的情况,不允许部分执行成功,要么全部成功,要不全部失败,部分成功的语句,在某一个失败的情况下,也必须进行回滚,保证数据的完整性和一致性。

为什么要引入事务?

例如在转账的情况下,如果转入成功,转出失败,就会造成银行数据不一致,损失金钱,所以要么全都成功,要不全部回滚。

再例如,生成订单的时候,如果订单成功,订单明细插入失败,那么订单和订单明细数据就无法对应,订单数据错乱,后果不堪设想。

事务的特性:

原子性(Atomicity)

事务不可分割,要么全部执行成功,要么全部执行失败

一致性(Durable)

事务执行前和执行后,数据状态保持一致

持久性(Durable)

事务一旦提交,数据即可持久化到数据库中,不可在回滚

隔离性(Isolation)

事务和事务在并发执行时,要相互隔离,隔离程度取决于隔离级别

事务代码

说明:注解事务非常简单,只需要一个@Transactional注解 即可


    /**
     * 转账
     * @param id 进id
     * @param id2 出id
     * @param money
     */
   @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,rollbackFor= Exception.class,readOnly = false  )
    public  void    transfer(Integer  id ,Integer  id2 ,Integer  money){
        try{
            userinfoMapper.add(id,money);
            userinfoMapper.minus(id2,money);
        }catch (Exception ex){
            throw   ex;

        }

    }

参数说明:

propagation

传播特性

事务方法和事务方法发生嵌套之后选择哪种传播方式

isolation

隔离级别

事务和事务在并发的时候采用的数据库隔离级别

rollbackFor

回滚异常类型

出现哪种异常才进行回滚

readOnly

是否只读

只读事务只适合查询,且不写入数据

Spring 事务的传播机制

Spring 事务传播机制定义了多个包含了事务的⽅法,相互调⽤时,事务是如何在这些⽅法间进⾏传递的。
Description

  • Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。

  • Propagation.SUPPORTS:如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。

  • Propagation.MANDATORY:(mandatory:强制性)如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。

  • Propagation.REQUIRES_NEW:表示创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法会新开启⾃⼰的事务,且开启的事务相互独⽴,互不⼲扰。

  • Propagation.NOT_SUPPORTED:以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。

  • Propagation.NEVER:以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。

  • Propagation.NESTED:如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。

Spring 中设置事务隔离级别
  • Isolation.DEFAULT:以连接的数据库的事务隔离级别为主。

  • Isolation.READ_UNCOMMITTED:读未提交,可以读取到未提交的事务,存在脏读。

  • Isolation.READ_COMMITTED:读已提交,只能读取到已经提交的事务,解决了脏读,存在不可重复读。

  • Isolation.REPEATABLE_READ:可重复读,解决了不可重复读,但存在幻读(MySQL默认级别)。

  • Isolation.SERIALIZABLE:串⾏化,可以解决所有并发问题,但性能太低。

其中的一些概念的说明:

脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一 个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。 那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

幻读:指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及 到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,就会发生操作第一个事务的用户发现表中还有 没有修改的数据行,也就是说幻像读是指同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读,就好象发生了幻觉一样。


Comment