transaction事务,即操作的原子性,spring的事务管理是基于数据库的事务机制来设置的。
下面是几个重要的概念:
1.事务具备ACID四种特性,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写。
2.事务的传播特性:是指spring对数据操作的事务管理行为,spring共定义了七种事务行为:
(1)propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是Spring默认的选择。
(2)propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
(3)propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
(4)propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
(5)propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
(6)propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
(7)propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作。
3.事务的隔离级别
(1)read uncommited:是最低的事务隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
(2)read commited:保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。
(3)repeatable read:这种事务隔离级别可以防止脏读,不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生(不可重复读)。
(4)serializable:这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读之外,还避免了幻象读。
4.spring中事务的几种实现方式:
(1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。
{编程式事务就是原生数据库操作来控制事务的完整性。}
(2)基于 TransactionProxyFactoryBean的声明式事务管理
1 <!-- 事务管理器 --> 2 3 <bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 4 <property name="dataSource" ref="dataSource"></property> 5 </bean> 6 7 <!-- 事务代理工厂 --> 8 <!-- 生成事务代理对象 --> 9 <bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 10 <property name="transactionManager" ref="myTracnsactionManager"></property> 11 <property name="target" ref="buyStockService"></property> 12 <property name="transactionAttributes"> 13 <props> 14 <!-- 主要 key 是方法 15 ISOLATION_DEFAULT 事务的隔离级别 16 PROPAGATION_REQUIRED 传播行为 17 --> 18 <prop key="add*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop> 19 <!-- -Exception 表示发生指定异常回滚,+Exception 表示发生指定异常提交 --> 20 <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop> 21 </props> 22 </property> 23 24 </bean>
(3)基于 @Transactional 的声明式事务管理
1 public class BuyStockServiceImpl implements BuyStockService{ 2 3 private AccountDao accountDao; 4 private StockDao stockDao; 5 6 @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED) 7 @Override 8 public void addAccount(String accountname, double money) { 9 accountDao.addAccount(accountname,money); 10 11 } 12 13 @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED) 14 @Override 15 public void addStock(String stockname, int amount) { 16 stockDao.addStock(stockname,amount); 17 18 } 19 } 20 21 <!-- 事务管理器 --> 22 <bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 23 <property name="dataSource" ref="dataSource"></property> 24 </bean> 25 26 <!-- 启用事务注解 --> 27 <tx:annotation-driven transaction-manager="myTracnsactionManager"/>
另外,<tx:annotation-driven transaction-manager="myTracnsactionManager"/> 是启动spring对事务的注解支持,同样的还有<mvc:annotation-driven> 等。tx:annotation-driven会有一个属性来指定事务管理,这里就是myTracnsactionManager。
(4)基于 aspectj aop 的事务管理
<tx:advice id="txAdvice" transaction-manager="DataSourceTransactionManager">
<!-- 为连接点指定事务属性 -->
<tx:attributes>
<tx:method name="query*" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 切入点配置 -->
<aop:pointcut expression="execution(org.yang.repository.provider.accessor.*)" id="point"></aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"></aop:advisor>
</aop:config>
tx:method属性详解:https://blog.csdn.net/qq_37272886/article/details/88638575
spring的org.springframework.jdbc.datasource.DataSourceTransactionManager会接管mybatis的数据库操作事务,即创建该事务管理器意味着事务可以交由spring来管理。spring提供了三种方法来完成事务管理,就是上面的三种。
参看博文:https://blog.csdn.net/qq_42914528/article/details/83743726 https://www.cnblogs.com/zienzir/p/9110817.html