spring提供的事务管理API
1. PlatformTransactionManager:平台事务管理器.
commit(TransactionStatus status)
getTransaction(TransactionDefinition definition)
rollback(TransactionStatus status)
2. TransactionDefinition:事务定义
ISOLation_XXX:事务隔离级别.
PROPAGATION_XXX:事务的传播行为.
过期时间:
3. TransactionStatus:事务状态
是否一个新的事务
事务是否已经提交
这三者之间的关系: PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.
PlatformTransactionManager:接口.
Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现
1. org.springframework.jdbc.datasource.DataSourceTransactionManager :
使用Spring JDBC或iBatis 进行持久化数据时使用
2. org.springframework.orm.hibernate3.HibernateTransactionManager:
使用Hibernate3.0版本进行持久化数据时使用
spring支持的两种事务管理:
1. 编程式的事务管理:
在实际中很少用到。 通过Transaction手动管理事务
2. 声明式的事务管理:
在实际中推荐使用(代码侵入量少),spring的声明式事务管理是通过AOP实现的。
编程式的事务管理:
<!-- 业务层类 -->
<bean id="accountService" class="org.westos.demo1.AccountServiceImpl">
<!-- 在业务层注入Dao -->
<property name="accountDao" ref="accountDao"/>
</bean>
<!-- 持久层类 -->
<bean id="accountDao" class="org.westos.demo1.demo1.AccountDaoImpl">
<!-- 注入连接池的对象,通过连接池对象创建模板. -->
<property name="dataSource" ref="dataSource"/>
</bean>
需要事务管理器:真正管理事务对象.
- Spring提供了事务管理的模板(工具类.)
第一步: 配置事务管理器
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 需要注入连接池,通过连接池获得连接 -->
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:配置事务模板类(TransactionTemplate)
<!-- 事务管理的模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
第三步:在业务层注入模板:(通过模板管理事务)
<!-- 业务层类 -->
<bean id="accountService" class="org.westos.demo1.demo1.AccountServiceImpl">
<!-- 在业务层注入Dao -->
<property name="accountDao" ref="accountDao"/>
<!-- 在业务层注入事务的管理模板 -->
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
第四步:在业务层代码上使用模板:
public void transfer(final String from, final String to, final Double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
accountDao.out(from, money);
int d = 1 / 0;
accountDao.in(to, money);
}
});
}
缺点: 代码量增加,代码有侵入性。
声明式事务管理
1. 原始方式(基于TransactionProxyFactoryBean)
原理:spring的配置文件对业务中需要进行事务管理的类生成一个TransactionProxyFactoryBean代理对象,来进行事务管理。
第一步:创建事务管理器:
<!-- 事务管理器 -->
<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">
<props>
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
第三步:编写测试类:
@Autowired
//注意注入的是代理对象
@Qualifier("accountServiceProxy")
private AccountService accountService;
public void test1(){
accountService.in(from,money);
}
缺点: 就是需要为每一个管理事务的类生成代理.需要为每个类都需要进行配置.
2.在(1)中的原始方式上有所改进(自动代理.基于切面):
原理:同样和(1)中一样也是生成一个代理对象来实现事务管理,但是使用了自动代理这样就改进了(1)中的缺点,不需要每一个需要事务管理的类都配置生成代理对象。
第一步:配置事务管理器:
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:定义一个通知类:
<!-- 定义一个增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 增强(事务)的属性的配置 -->
<tx:attributes>
<!--
isolation:DEFAULT :事务的隔离级别.
propagation :事务的传播行为.
read-only :false.不是只读
timeout :-1
no-rollback-for :发生哪些异常不回滚
rollback-for :发生哪些异常回滚事务
-->
<tx:method name="transfer"/>
</tx:attributes>
</tx:advice>
第三步:切点和通知的结合:
<!-- aop配置定义切面和切点的信息 -->
<aop:config>
<!-- 定义切点:哪些类的哪些方法应用增强 -->
<aop:pointcut expression="execution(* org.westos.demo1.AccountService+.*(..))" id="mypointcut"/>
<!-- 定义切面: -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
</aop:config>
3:基于注解的声明式事务管理:
第一步:配置事务管理器:
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:启用事务管理的注解:
<!-- 开启注解的事务管理 -->
<tx:annotation-driven />
第三步:在业务类中所需要事务管理的方法上使用注解:
@Transactional
//注解中有属性值:
//isolation
//propagation
// readOnly
@Transactional注解详解:
默认情况下,只有方法出现的 是RuntimeException或Error以及它们的子类时(未检查异常),才会导致事务回滚
如果要改变默认情况
@Transactional(rollbackFor=异常类.class)
那么方法如果出现了该异常,或该异常的子类异常时,就会回滚
@Transactional(noRollbackFor=异常类.class)
当遇到这种异常时,不会回滚事务
最后要注意的是,在业务方法中不要自己try-catch捕获异常,否则spring无法自动回滚事务
@Transactional(isolation = 隔离级别)
@Transactional(timeout = 超时时间(秒))
@Transactional(readOnly = true|false) true表示只读(只有查询) false(会有增删改)设置为true,性能会有所提升,但是底层数据库驱动支持(对mysql支持)