Spring 知识点总结 之 事务管理
2017-03-15 18:58
399 查看
Spring的事务管理
事务
逻辑上的一组操作,要不全部成功,要不全部失败。原子性
隔离性
一致性
几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致
持久性
在没有事务导致的问题
读问题脏读
读到了未提交的数据
虚读
读到了其他事务提交的数据,导致两次查询结果集数量不同
不可重复读
读到了其他事务提交的数据,导致统一条记录,两次查询结果不同
写问题
丢失更新
解决方法
读问题 通过设置事务的隔离级别解决。写问题 通过乐观锁、悲观锁解决。
Spring的事务管理的API
PlatformTransactionManager 事务管理器TransactionDefinition 事务隔离级别、传播策略
TransactionStatus 事务状态
关系:平台事务管理器真正管理事务对象.根据事务定义的信息TransactionDefinition.进行事务管理.在管理事务中产生一些状态.将状态记录到TransactionStatus中.
事务管理器常见的实现类(与使用的数据库连接池有关)
DataSourceTrsansactionManager (Spring JDBC 或 Mybatis)HibernateTransactionManager (Hibernate)
JpaTransactionManager (JPA)
顶层接口方法
getTransaction(TransactionDefinition)
commit(TransactionStatus)
rollback(TransactionStatus)
事务定义
// IntelliJ API Decompiler stub source generated from a class file // Implementation of methods is not available package org.springframework.transaction; public interface TransactionDefinition { int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; int TIMEOUT_DEFAULT = -1; int getPropagationBehavior(); int getIsolationLevel(); int getTimeout(); boolean isReadOnly(); java.lang.String getName(); }
ISOLATION_* :事务隔离级别
ISOLATION_DEFAUTL :
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
PROPAGATION_*: 事务传播行为:A、B为使用 同一个数据库连接的方法。
PROPAGATION_REQUIRED :A中有事务,使用A中的事务.如果没有B就会开启一个新的事务,将A包含进来.(保证A,B在一个事务中)
PROPAGATION_SUPPORTS :A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.
PROPAGATION_MANDATORY :A中有事务,使用A中的事务.如果A没有事务.抛出异常.
PROPAGATION_REQUIRES_NEW :A中有事务,将A中的事务挂起.创建一个新的事务.(保证A,B没有在一个事务中)
PROPAGATION_NOT_SUPPORTED :A中有事务,将A中的事务挂起.
PROPAGATION_NEVER :A中有事务,抛出异常.
PROPAGATION_NESTED :嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)
TransactionStatus 事务的状态
boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); void flush(); boolean isCompleted();
Spring 事务配置(编程式事务)
不做赘述,了解即可(很少使用)Spring为了简化事务管理的代码:提供了模板类.TransactionTemplate. 步骤一:配置一个事务管理器. <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> 步骤二:配置事务管理的模板: <!-- 配置事务管理的模板 --> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean> 步骤三:在需要进行事务管理的类中,注入事务管理的模板. <!-- 配置业务层的类 --> <bean id="accountService" class="com.itheima.spring.demo1.AccountServiceImpl"> <property name="accountDao" ref="accountDao"/> <!-- 注入事务管理的模板 --> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> 步骤四:在业务层使用模板管理事务: @Override public void transfer(final String out, final String in, final Double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { accountDao.outMoney(out, money); int d = 1 / 0; accountDao.inMoney(in, money); } }); }
Spring 事务配置 (声明式事务 使用AOP实现)
Spring 通过ProxyFactoryBean 实现自动代理<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置生成代理:增强业务层类 --> <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 配置目标类 --> <property name="target" ref="accountService"/> <!-- 注入事务管理器 --> <property name="transactionManager" ref="transactionManager"/> <!-- 配置事务的相关属性 --> <property name="transactionAttributes"> <!-- prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception --> <props> <prop key="transfer">PROPAGATION_REQUIRED</prop> </props> </property> </bean>
通过 AspectJ 实现代理(重点掌握)
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务增强 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- propagation :传播行为 isolation :隔离级别 read-only :是否只读 timeout :超时信息 rollback-for:发生哪些异常回滚. no-rollback-for:发生哪些异常不回滚. --> <tx:method name="transfer" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置AOP切面产生代理 --> <aop:config> <aop:pointcut expression="execution(* com.itheima.spring.demo3.AccountService+.*(..))" id="pointcut1"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> </aop:config>