https://www.bilibili.com/video/av47952931
p72-74
基于XML的事务控制
2个工具类:ConnectionUtils 和 TransactionManager
见 Spring笔记09 事务控制的问题&动态代理
主要配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <bean id="connectionUtils" class="com.itheima.utils.ConnectionUtils"> <property name="dataSource" ref="dataSource"></property> </bean>
<bean id="txManager" class="com.itheima.utils.TransactionManager"> <property name="connectionUtils" ref="connectionUtils"></property> </bean>
<aop:config> <aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut> <aop:aspect id="txAdvice" ref="txManager"> <aop:before method="beginTransaction" pointcut-ref="pt1"></aop:before> <aop:after-returning method="commit" pointcut-ref="pt1"></aop:after-returning> <aop:after-throwing method="rollback" pointcut-ref="pt1"></aop:after-throwing> <aop:after method="release" pointcut-ref="pt1"></aop:after> </aop:aspect> </aop:config>
|
基于注解的AOP配置
xml中要开启对注解的支持
1 2 3 4 5 6 7 8 9
| @Service("accountService") public class AccountServiceImpl implements IAccountService{
@Autowired private IAccountDao accountDao; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Repository("accountDao") public class AccountDaoImpl implements IAccountDao {
@Autowired private QueryRunner runner;
@Autowired private ConnectionUtils connectionUtils; }
|
1 2 3 4 5 6 7 8 9
| @Component("connectionUtils") public class ConnectionUtils {
@Autowired private DataSource dataSource; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Component("txManager") @Aspect public class TransactionManager {
@Autowired private ConnectionUtils connectionUtils;
@Pointcut("execution(* com.itheima.service.impl.*.*(..))") private void pt1(){} @Around("pt1()") public Object aroundAdvice(ProceedingJoinPoint pjp){ Object rtValue = null; try { Object[] args = pjp.getArgs(); this.beginTransaction(); rtValue = pjp.proceed(args); this.commit();
return rtValue;
}catch (Throwable e){ this.rollback(); throw new RuntimeException(e); }finally { this.release(); } } }
|
如果分别在开启事务、提交事务、回滚事务、释放连接的函数上分别加@Before(“pt1()”)、@AfterReturning(“pt1()”)、@AfterThrowing(“pt1()”)、@After(“pt1()”)
理论上没毛病。但是!Spring实际的执行顺序是有问题的(同 见笔记9)
最终通知在后置通知之前执行了,于是根本没有提交就释放了,连接已经变成了新的连接
所以不要分别用。用一个环绕通知,里面try-catch,自己控制顺序