spring事物传播机制和隔离级别

本文探讨了在并发环境下,事务运行可能遇到的脏读、不可重复读和幻读问题,并详细介绍了Spring中的四种事务隔离级别,以及如何防止这些问题的发生。此外,文章还阐述了Spring的七种事务传播机制,包括其各自的行为和适用场景。

事物并发运行可以造成的问题

1.脏读  读取到另一个事物修改但还未提交的数据

2.不可重复读   是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

3.幻读 一个事物读取几行记录后  另一个事物操作了数据  ,在后来的查询中第一个事务就会发现有些原来没有的记录。

(例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样)

 

事物隔离级别

1、读未提交(READ_UNCOMMITED):允许读取还未提交的改变了的数据。可能导致脏读、幻读、不可重复读。

2、读已提交(READ_COMMITED):允许在并发事务已经提交后读取。可防止脏读,但幻读、不可重复读仍可能发生。

3、可重复读(REPEATABLE_READ):对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏读、不可重复读。但幻读仍可能发生。

4、可串行化(SERIALIZABLE):完全服从ACID的隔离级别,确保不发生脏读、幻读和不可重复读。他在所有的隔离级别中是最慢的,因为要完全锁住在事务中涉及的数据表。

5、Default:使用了后端数据库默认的隔离级别(spring中的选择项,也是isolation属性的默认值,Mysql默认采用REPEATABLE_READ隔离级别,Oracle默认采用READ_COMMITED隔离级别)。

事物传播机制 spring有7总种传播机制

1、PROPAGATION_REQUIRED:支持当前事务,如果当前不存在事务则新建一个。

2、PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务。

3、PROPAGATION_MANDATORY:支持当前事务,如果不存在,则抛出异常。

4、PROPAGATION_REQUIRES_NEW:如果当前有事务存在,挂起当前事务,创建一个新的事务。

5、PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前有事务存在,挂起当前事务。

6、PROPAGATION_NEVER:以非事务方式运行,如果当前有事务存在,抛出异常。

7、PROPAGATION_NESTED:如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。
 

spring隔离级别和事物传播机制配置

<tx:advice id="txAdvice" transaction-manager="transactionManager">
     <tx:attributes>
          <tx:method name="query*" read-only="true" propagation="SUPPORTS" />
          <tx:method name="get*" read-only="true" propagation="SUPPORTS" />
          <tx:method name="insert*" propagation="REQUIRED" />
          <tx:method name="save*" propagation="REQUIRED" />
          <tx:method name="update*" propagation="REQUIRED" />
          <tx:method name="remove*" propagation="REQUIRED" />
          <tx:method name="delete*"  propagation="REQUIRED" />
     </tx:attributes>
</tx:advice>
由于没有给method配置isolation属性,所以默认是isolation=‘DEFAULT’,也就是使用后端数据库默认的隔离级别。

 


 

### 配置Spring事务传播机制隔离级别Spring框架中,可以通过`@Transactional`注解灵活配置事务传播机制隔离级别。该注解支持多种传播行为隔离级别,适用于不同的业务场景。 #### 1. 配置事务传播机制 Spring支持7种事务传播机制,常用的包括`PROPAGATION_REQUIRED`(默认值)`PROPAGATION_REQUIRES_NEW`。这些传播机制可以通过`@Transactional(propagation = Propagation.XXX)`进行配置。 例如,配置一个方法使用`PROPAGATION_REQUIRED`传播机制: ```java @Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 方法A的业务逻辑 } ``` 如果希望方法独立于当前事务执行,可以使用`PROPAGATION_REQUIRES_NEW`: ```java @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { // 方法B的业务逻辑(独立事务) } ``` #### 2. 配置事务隔离级别 Spring支持5种事务隔离级别,包括`ISOLATION_DEFAULT`(默认使用底层数据库的隔离级别`ISOLATION_SERIALIZABLE`(最高隔离级别)。可以通过`@Transactional(isolation = Isolation.XXX)`进行配置。 例如,配置一个方法使用`ISOLATION_READ_COMMITTED`隔离级别: ```java @Transactional(isolation = Isolation.READ_COMMITTED) public void methodC() { // 方法C的业务逻辑 } ``` 如果需要使用最高隔离级别,避免所有并发问题,可以配置为`ISOLATION_SERIALIZABLE`: ```java @Transactional(isolation = Isolation.SERIALIZABLE) public void methodD() { // 方法D的业务逻辑 } ``` #### 3. 综合配置示例 以下是一个综合示例,展示如何在同一个方法中同时配置传播机制隔离级别: ```java @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ) public void methodE() { // 方法E的业务逻辑 } ``` 此配置表示方法E将在独立事务中执行,并且使用可重复读的隔离级别。这种配置适用于需要独立事务且要求较高数据一致性的业务场景。 #### 4. 注意事项 - **事务失效问题**:确保方法被`@Transactional`注解标记,并且是`public`方法。如果事务方法被内部调用,由于Spring的代理机制事务可能不会生效。 - **多数据源事务管理**:在多数据源场景下,事务管理可能需要额外的配置,例如使用JTA(Java Transaction API)或分布式事务管理器。 - **事务超时设置**:可以通过`@Transactional(timeout = 30)`设置事务的超时时间,避免长时间占用数据库资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值