关于spring 中的事务

1.什么是事务

我们在实际业务场景中,经常会遇到数据频繁修改读取的问题。在同一时刻,不同的业务逻辑对同一个表数据进行修改,

这种冲突很可能造成数据不可挽回的错乱,所以我们需要用事务来对数据进行管理。

并发事务导致的问题

(1)第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖

(2)脏读:一个事务读取到另一个事务未提交的更新数据。

(3)幻读也叫虚读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。

(4)不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。

2. 事务的五个隔离级别

DEFAULT : 数据库的默认事务隔离级别

READ_UNCOMMITTED : 读未提交 。 未解决任何并发问题

READ_COMMITTED : 读已提交。解决脏读,存在不可重复读与幻读。

REPEATABLE_READ : 可重复读。解决脏读,不可重复读,存在幻读。

SERIAIZABLE : 串行化。不纯在并发问题。

3.事务的传播行为

REQUIRED : 指定的方法必须在事务内执行。若当前存在事务,就加入到当前事务中;若当前没有事务就新建一个事务。

SUPPORTS : 指定方法支持事务,如果没有事务也可以执行。 适合查询操作。 如果有事务就就执行事务吗,没有事务也执行

MANDATORY  : 必须有事务,没事务就抛出异常

REQUIRES_NEW : 总是新建个事务,若当前方法有事务,也新建一个事务,之前的事务挂起

NOT_SUPPORTED : 纯在事务也不执行事务,一般没啥用

NEVER : 有事务就抛异常 : 也没啥用

NESTED : 如果存在事务,就嵌套事务执行,没事务就新建

4. Spring 事务代理工厂

 <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> 

  <property name="dataSource" ref="myDataSource"/> 指定数据库数据源

</bean> 
<!-- 注册事务代理工厂类 -->  
<bean class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" id="stockServiceProxy">  创建了一个代理对象
   <!-- 指定事务管理器 -->  
  <property name="transactionManager" ref="transactionManager"/> 
    <!-- 指定目标对象 -->  
    <property name="target" ref="stockService"/> 指定的service对象
    <!-- 指定事务的属性(事务定义接口的中的三类常量值) --> 
    <property name="transactionAttributes"> 
      <props> 
      <!-- 指定业务方法的具体事务属性 -->   <!-- key="业务方法名,可以使用通配符*" 值:指定事务定义接口中常量值(隔离级别,传播行为,超时) readOnly:优化指示器(给数据库看的) -->     
        <prop key="select*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop> 传播行为  隔离级别
        <prop key="find*">ISOLATION_DEFAULT,PROPAGATION_SUPPORTS,readOnly</prop>  readOnly 表示数据是只读的可以提高效率
        <prop key="指定的service对象具体方法">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop> 
      </props>
     </property> 
</bean>

 Spring 使用 事务注解

  @Transactional

  需要 开启事务注解驱动

  <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="myDataSource"/> </bean>
  <!-- 开启事务注解驱动 transaction-manager:指定事务管理器bean的id -->
   <tx:annotation-driven transaction-manager="transactionManager"/>

  @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor={StockException.class})
  @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)

猜你喜欢

转载自www.cnblogs.com/zhengminghui/p/11330298.html