4.2 Spring中对事务的整合
在Spring中,所有操作事务的类都继承自 PlatformTransactionManager
4.2.1 事务的隔离级别
- ISOLATION_READ_UNCOMMITTED:读未提交
- ISOLATION_READ_COMMITTED:读已提交
- ISOLATION_REPEATABLE_READ:可重复读
- ISOLATION_SERIALIZABLE:串行化
4.2.2 脏读、不可重复读、幻读
脏读:A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。例如常见的取款事务和转账事务:
不可重复读:不可重复读是指A事务读取了B事务已经提交的更改数据。假如A在取款事务的过程中,B往该账户转账100,A两次读取的余额发生不一致。
幻读:A事务读取B事务提交的新增数据,会引发幻读问题。幻读一般发生在计算统计数据的事务中,例如银行系统在同一个事务中两次统计存款账户的总金额,在两次统计中,刚好新增了一个存款账户,存入了100,这时候两次统计的总金额不一致。
4.2.3 事务的七种传播行为
什么是事务的传播行为:事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。
案例
Dao层接口
//加钱的方法 void addMoney(double money); //减钱的方法 void subMoney(double money);
实现类
@Override public void addMoney(double money) { String sql="update account set balance=balance+? where accountname='cmy'"; this.getJdbcTemplate().update(sql,money); } @Override public void subMoney(double money) { String sql="update account set balance=balance-? where accountname='王五'"; this.getJdbcTemplate().update(sql,money); }
Service接口
void transferMoney(double money);
实现类
@Override public void transferMoney(double money) { //金额先减后加 dao.subMoney(money); //模拟计算机异常 int result=5/0; dao.addMoney(money); }配置(工厂)
<!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--配置Spring 事务的代理工厂--> <bean id="transactionFactory" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"/> <property name="target" ref="accountService"/> <property name="transactionAttributes"> <props><!--键值 key为具体的方法名 value可以为传播行为或隔离级别--> <prop key="transferMoney">ISOLATION_READ_COMMITTED</prop> </props> </property> </bean>
aop方式配置事务
<!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
使用注解方式配置
<!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--开启事务的注解配置--> <tx:annotation-driven/>
测试
public class Demo2 { public static void main(String[] args) { ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml"); //从Spring容器中获取事务代理工厂对象 AccountService us=(AccountService)app.getBean("transactionFactory"); //转账 us.transferMoney(1000); } }