Spring事物管理
事物管理
spring封装了事务管理的代码,包括打开事物,提交事物,回滚事物.
因为在不同的平台操作事务的代码各不相同,因此spring提供了一个接口PlatformTransactionManager接口,在不同的平台下提供不同的实现类
注意:在Spring中玩事务管理,最为核心的对象就是TransactionManager
Spring管理事务的属性介绍
- 选择事务的隔离级别
- 选择是否只读
- 事务的传播行为:决定业务方法之间调用,事务应该如何处理
Transaction模板(了解)
spring管理事务的方式管理事物的方式分为三种
首先,这三种方法的共有步骤就是将核心的事物管理器配置到Spring容器中,如下
<!-- 事务核心管理器,封装了所有的事务操作,依赖于连接池 --> <bean name ="transactionManager" class=" org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--事务的模板对象 --> <bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"></property> </bean>
以转账的例子为例,首先在Dao层创建AccountDaoImpl类,实现转账的方法
AccountDao:
public interface AccountDao { void increaseMoney(Integer id,Double money); void decreaseMoney(Integer id,Double money); }
AccountDaoImpl:
import org.springframework.jdbc.core.support.JdbcDaoSupport; public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void increaseMoney(Integer id, Double money) { getJdbcTemplate().update("update t_account set money = money+? where id =?", money,id); } @Override public void decreaseMoney(Integer id, Double money) { getJdbcTemplate().update("update t_account set money = money-? where id =?", money,id); } }
当然,在applicationContext.xml中先配置好连接池对象

<!-- 1、连接池 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 2、Dao --> <bean name="accountDao" class="com.tz.dao.AccountDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean>
编码式(了解)
使用编码式首先要给Service层注入一个TransactionTemplate对象
AccountService:

public interface AccountService { void transfer(Integer from,Integer to, Double money); }
AccountServiceImpl:

import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.tz.dao.AccountDao; public class AccountServiceImpl implements AccountService { private AccountDao ad; private TransactionTemplate tt; // @Override public void transfer(final Integer from,final Integer to,final Double money) { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus arg0) { // 在这里面实现事物逻辑 ad.decreaseMoney(from, money); int i = 1/0; ad.increaseMoney(to, money); } }); } public void setAd(AccountDao ad) { this.ad = ad; } public void setTt(TransactionTemplate tt) { this.tt = tt; } }
在上面的代码中 doInTransactionWithoutResult() 已经帮我们完成了开始事物,关闭事物,回滚事物的操作,我们只要专心进行操作即可
另:上面的代码只是观光代码,一般不会用在生产中
xml配置(Aop重点)
使用xml配置首先需要在配置文件中配置事物通知跟织入,当然,在这之前要先导入tx约束跟aop约束

<!-- 配置事务通知 --> <tx:advice id="txAdvisor" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> </tx:attributes> </tx:advice> <!-- 配置织入 --> <aop:config> <aop:pointcut expression="execution(* com.tz.service.*ServiceImpl.*(..))" id="txPc"/> <!-- 配置切面 --> <aop:advisor advice-ref="txAdvisor" pointcut-ref="txPc"/> </aop:config>
上面的参数说明:
- isolation:隔离级别
- propagation:传播行为
- read-only:是否只读
上面的配置完成后就会自动去匹配Service里面的方法,不必在Service中再做什么操作
import com.tz.dao.AccountDao; public class AccountServiceImpl implements AccountService { private AccountDao ad; @Override public void transfer(final Integer from,final Integer to,final Double money) { ad.decreaseMoney(from, money); int i = 1/0; ad.increaseMoney(to, money); } }
注解配置(Aop重点)
使用注解配置的道理跟xml配置差不多
使用注解只需要在配置文件中配置里面开启一下注解即可
<!-- 开启注解 -->
<tx:annotation-driver transaction-manager="transactionManager" />
然后要对哪个方法使用事物模板就在那个方法上面配置上注解,或者在类上面配置上注解对整个类的方法都有效,如果该类中有极个别的方法配置的参数不同,只需要在对应的方法上配置上注解即可,然后类的注解便不会对该方法有效
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; import com.tz.dao.AccountDao; @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true) public class AccountServiceImpl implements AccountService { private AccountDao ad; @Override @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false) public void transfer(final Integer from,final Integer to,final Double money) { ad.decreaseMoney(from, money); int i = 1/0; ad.increaseMoney(to, money); } }
如上配置即可