Spring的事务管理
声明式
配置文件。xml
声明式的事务管理是基于Aop思想来的,所以要引入aop相关jar包。
<!-- 引入外部属性文件.property-->
<!-- 配置c3p0连接池-->
<!-- 配置业务层类-->
<!-- 配置DAO的类-->
<!-- 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--事务管理器需要引入连接池,有了连接池才有了相应的连接,才可以帮我们进行事务管理-->
<property name = "dataSource" ref="dataSource"/>
</bean>
<!-- 配置业务层的代理-->
<!-- Spring为我们提供了以TransactionProxyFactoryBean帮我们某一个类产生代理对象-->
<bean id="accountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--首先配置你要增强的类是谁-->
<property name="target" ref="accountService"/>
<!--其次是要把真正的事务管理器引入进来-->
<property name="transactionManager" ref="transactionManager"/>
<!--具体要怎么进行管理,当然还是要注入事务的属性-->
<property name="transactionAttributes">
<props>
<!--
prop的格式:
*PROPAGATION:事务的传播行为
*ISOLATION:事务的隔离级别
*readOnly:只读(如果设定了这个属性,则业务层无法对数据库进行修改)
*-Exception:发生哪些异常则回滚事务不进行提交
*+Exception:发生哪些异常不回滚事务,直接进行提交
-->
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
业务层实现类
public class AccountServiceImpl implements AccountService{
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao){
this.accountDao=accountDao;
}
public void transfer(String out,String in,Double money){
accountDao.outMoney(out,money);
accountDao.inMoney(in,money);
}
}
写一个测试类
@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
//要测试某个类当然要将其注入进来
//但是如果要使用声明式注入管理,则应该讲增强的业务层传输进来进行测试,增强的业务类,其实就是在xml文件中配置的那个业务层的代理
//@Resource(name="accountService")
@Resource(name="accountServiceProxy")
private AccountService accountService;
@Test
//调用service中的业务方法
accountService.transfer("aaa","bbb",200d);
}
基于AspectJ开发声明式事务管理
aspectJ是一种第三方的用于简化Spring AOP开发的框架。
- 第一步当然是要引入AspectJ的jar包和Spring整合AspectJ的包。
- 将Dao和Service的接口和实现类写好
- 新建一个xml配置文件,把Dao和service声明好。依赖关系也声明好。
<!--配置c3p0连接池-->
<bean id ="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置也就是事务的通知(一个增强)-->
<!--
propagation:事务传播行为
isolation:事务隔离级别
readOnly:只读性,无法进行增删改查
rollback-for:发生哪些异常回滚
no-rollback-for:发生哪些异常不回滚
timeout: 过期信息
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut expression="execution(*cn.muke.spring.demo3.AccountService+.*(..))" id="pointcunt1"/>
<!--配置切面,一个切面用advisor-->
<aop: advisor advice-ref=txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
- 新建一个测试的类
@RunWith(SpringJunit4ClassRunner.CLASSS)
@ContextConfiguration("classpath:applicationContext3.xml")
public class SpringDemo3{
@Resource(name="accountService")
private AccountService accountService;
@Test
public void demo1(){
accountService.transfer("aaa","bbb",200d);
}
}
基于注解的方法
- 首先仍然是把DAO和service的接口和实现类
- 创建一个xml文件,配置好DAO和service
//无论你使用的是什么方式的事务管理,但是都需要配置事务管理器,因为它才是真正的事务管理器
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransationManager>
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启注解事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
开启了注解事务后,哪个类需要管理事务,就给那个类上添加注解。@Transactional
注解也是有属性的。需要在@Transaction()括号里添加。
- 写一个单元测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext$.xml")
@Resource(name="accountService")
private AccountService accountService;
@Test
public void demo1(){
accountService.transfer("aaa","bbb",200d);
}
}