Spring事务管理
- 事务回顾
- 什么是事务?
- 事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败
- 事务的特性
- 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
- 一致性指事务前后数据的完整性必须保持一致
- 隔离性指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要互相隔离
- 持久性是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,即使数据库发生故障也不对其由任何影响
- 什么是事务?
- Spring事务管理的一组API
- Spring接口介绍
- Spring事务管理高层抽象主要包括3个接口
- Platform TransactionManager 平台事务管理器
- Spring为不同的持久层框架提供了不同Platform TransactionManager接口实现
- org.framework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC 或 iBatis进行持久层数据使用
- org.framework.orm.hibernate3.HibernateTransactionManager:使用Hibernate3.0版本进行持久层数据使用
- org.framework.orm.jpa.JpaTransactionManager:使用JPA进行持久层时使用
- org.framework.jdo.JdoTransactionManager:当持久层机制是Jdo时使用
- org.framework.transaction.jta.JtaTransactionManager:使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用
- Spring为不同的持久层框架提供了不同Platform TransactionManager接口实现
- TransactionDefinition 事务定义信息(隔离、传播、超时、只读)
- 如果不考虑隔离性,会引发安全问题如下:
- 脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的
- 不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同
- 虚读(幻读)
- 一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了
- 再后来的查询中,第一个事务就会发现有些原来没有的记录
- 事务隔离级别(四种)和含义
- DEFAULT:使用后端数据库默认的隔离级别(spring中的选择项)
- READ_UNCOMMITED:允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读
- READ_COMMITTED:允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生
- REPEATABLE_READ:对相同字段的多次读取是一致的,除非数据被事物本身改变
- SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的
- Mysql默认采用REPEATABLE_READ隔离级别
- Oracle默认采用READ_COMMITTED隔离级别
- 事务传播
- 阿
- 阿
- 如果不考虑隔离性,会引发安全问题如下:
- TransactionStatus 事务具体运行状态
- Platform TransactionManager 平台事务管理器
- Spring事务管理高层抽象主要包括3个接口
- Spring接口介绍
Spring支持两种方式事务处理
Spring的编程式事务管理
- 环境准备
- 创建mySQL数据表
- 创建web工程
- 导入jar包
- 在src目录编写配置
- applicationCOntext.xml
- log4j.properties(抄的)
- jdbc.propertie
- 编写Service注入DAO
- 编写DAO注入 注入JdbcTemplate
- 在AccountService中使用TransactionTemplate
- TransactionTemplate依赖DataSourceTransactionManager
DataSourceTransactionManager依赖DataSource构造
“`<bean id="accountService" class="spring.AccountService"> <property name="accountDAO" ref="accountDAO"></property> <property name="transactionTemplate" ref="transactionTemplate"></property> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"></property> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
“`
- 等
Spring的声明式事务管理
使用XML配置声明式事务(原始方式)
使用原始的ransactionroxyFactoryBean
<!-- 配置业务层类 --> <bean id="accountService" class="spring2.AccountServiceImpl"> <property name="accountDAO" ref="accountDAO"></property> </bean> <!-- AOP的方式 --> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置业务层的代理 --> <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 配置目标对象 --> <property name="target" ref="accountService"> </property> <!-- 注入事务管理器 --> <property name="transactionManager" ref="transactionManager"> </property> <!-- 注入事务管理 --> <property name="transactionAttributes"> <props> <!-- prop的格式 : * PROPAGATION: 事务的传播行为 * ISOLATION: 事务的隔离级别 * readOnly: 只读.(不可以进行修改,插入,删除) * -Exception: 发生某些异常则回滚事务 * +Exception: 发生某些异常事务却不回滚事务 --> <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> <!-- +Exception演示: <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> --> </props> </property> </bean>
使用XML配置声明式事务 基于AspectJ、tx、aop
<!-- 配置业务层类 -->
<bean id="accountService" class="spring3.AccountServiceImpl">
<property name="accountDAO" ref="accountDAO"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务的通知:(事务的增强) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
* propagation: 事务的传播行为
* isolation: 事务的隔离级别
* read-only: 只读.(不可以进行修改,插入,删除)
* rollback-for: 发生某些异常则回滚事务
* no-rollback-for: 发生某些异常事务却不回滚事务
* timeout: 国企信息
-->
<tx:method name="transfer" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* spring3.AccountService+.*(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
使用XML配置声明式事务 基于注解
applicationContext.xml <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> 业务类: @Transaction注解中的属性: propagation:事务的传播行为 isolation:事务的隔离级别 readOnly:只读 rollbackFor:发生指定的异常则回滚 noRollbackFOR:发生指定的异常则不回滚 @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.DEFAULT,readOnly=false) public class AccountServiceImpl implements AccountService { // 注入转账的DAO类 private AccountDAO accountDAO; public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } @Override public void transfer(String out, String in, Double money) { // TODO Auto-generated method stub accountDAO.outMoney(out, money); int i = 1/0; accountDAO.inMoney(in, money); } }
- 总结:
- Spring将事务管理分成了两类:
- 编程式事务管理
- 手动编写代码进行事务管理(很少使用)
- 声明式事务管理
- 基于TransactionProxyFactoryBean的方式。(很少使用)
- 需要为每个进行事务管理的类,配置一个TransactionProxyFactoryBean进行增强
- 基于AspectJ的XML方式.(经常使用)
- 一旦配置好以后,类上不需要田间任何东西。
- 基于注解方式。(经常使用)
- 配置简单.需要在业务层上添加一个@Transactional的注解
- 编程式事务管理
- Spring将事务管理分成了两类: