编程式事务控制相关对象
PlatformTransactionManager
PlatformTransactionManager 接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法。
注意:PlatformTransactionManager是接口类型,只提供一种规范,不同的dao层实现有不同的实现类
TransactionDefinition
事务并发可能引发的问题:
脏读: 一个事务读到了另一个未提交事务修改过的数据
不可重复读:一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。
幻读:一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
事务的隔离级别:
ISOLATION_DEFAULT(默认)
ISOLATION_READ_UNCOMMITTED(读未提交)会出现:脏读,不可重复读,幻读
ISOLATION_READ_COMMITTED (读已提交)会出现:不可重复读,幻读
ISOLATION_REPEATABLE_READ (可重复读)会出现:幻读
ISOLATION_SERIALIZABLE(可串行化)
事务传播行为:
REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务) MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
NEVER:以非事务方式运行,如果当前存在事务,抛出异常
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作
超时时间:默认值是-1,没有超时限制。如果有,以秒为单位进行设置
是否只读:建议查询时设置为只读
TransactionStatus
基于 XML 的声明式事务控制
Spring 声明式事务控制底层就是AOP。
声明式事务控制明确事项: 谁是切点? 谁是通知? 配置切面?
声明式事务控制的实现
引入tx命名空间和对标信息
配置事务增强和事务织入
<!--平台事务管理器-->
<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>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 事务的aop织入-->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* org.example.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"></aop:advisor>
</aop:config>
测试
public void save(String outMan, String inMan, int money){
testDao.show1(outMan,money);
int i = 10/0;
testDao.show2(inMan,money);
}
最终数据库中的信息没有发生改变
切点方法的事务参数的配置
声明式事务控制的配置要点:
平台事务管理器配置(不同框架有不同的管理器)
事务通知的配置
事务aop织入的配置
基于注解的声明式事务控制