编程式事务
先认识几个接口
1.PlatformTransactionManager 平台事务管理接口 -》springjdbc的实现类DataSourceTransactionManager
2.TransactionDefinition 事务定义 -》实现类DefaultTransactionDefinition
3.TransactionStatus 事务状态
public void transfer(String outName,String inName,Double money){
//创建事务管理器
DataSourceTransactionManager dstm = new DataSourceTransactionManager();
//为事务管理器设置与数据层相同的数据源,可以用set,也可以用构造方法
dstm.setDataSource(dataSource);
//创建事务定义对象
TransactionDefinition td = new DefaultTransactionDefinition();
//创建事务状态对象,用于控制事务执行
TransactionStatus ts = dstm.getTransaction(td);
accountDao.inMoney(outName,money);
int i = 1/0; //模拟业务层事务过程中出现错误
accountDao.outMoney(inName,money);
//提交事务
dstm.commit(ts);
}
AOP改造事务
-
把事务相关的共性功能抽取处理组成AOP的通知
public Object tx(ProceedingJoinPoint pjp) throws Throwable { DataSourceTransactionManager dstm = new DataSourceTransactionManager(); dstm.setDataSource(dataSource); TransactionDefinition td = new DefaultTransactionDefinition(); TransactionStatus ts = dstm.getTransaction(td); Object ret = pjp.proceed(pjp.getArgs()); dstm.commit(ts); return ret; }
-
配置AOP通知bean,事务中要有数据源,所以要注入dataSource
<bean id="txAdvice" class="com.itheima.aop.TxAdvice"> <property name="dataSource" ref="dataSource"/> </bean>
-
将通知织入到切入点中
<aop:config> <aop:pointcut id="pt" expression="execution(* *..transfer(..))"/> <aop:aspect ref="txAdvice"> <aop:around method="tx" pointcut-ref="pt"/> </aop:aspect> </aop:config>
声明式事务
-
添加命名空间tx
-
构造一个事务管理器相当于上文中的通知类
<bean id = "txManager" class = "org.springframework.jdbc.DataSourceTransactionManager"> <property name = "dataSource" ref = "dataSource"></property> </bean>
-
配置tx:advice 定义事务管理的通知类
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" read-only="false" /> <tx:method name="get*" read-only="true" /> <tx:method name="find*" read-only="true" /> </tx:attributes> </tx:advice>
-
配置aop 使用aop:advisor标签配置专属事务通知类
<aop:config> <aop:pointcut id="pt" expression="execution(* *..*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config>
声明式事务(注解)
-
<tx:annotation-driven transaction-manager = "事务管理器"></tx:annotation-driven> <!--注解驱动还需要配置事务管理器-->
-
纯注解-注解驱动扫描 @EnableTransactionManagement
@Configuration @ComponentScan("com.itheima") @PropertySource("classpath:jdbc.properties") @Import({JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class}) //事务的注解驱动扫描 @EnableTransactionManagement public class SpringConfig { }
//构造事务管理器 public class TransactionManagerConfig { @Bean public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } }
-
对方法或者接口或者类设置事务 @Transactional
@Transactional( readOnly = false, timeout = -1, isolation = Isolation.DEFAULT, rollbackFor = {ArithmeticException.class, IOException.class}, noRollbackFor = {}, propagation = Propagation.REQUIRES_NEW )