记一次spring注解开启失败的经历
1.项目中注解开启事务配置
如有多个org.springframework.jdbc.datasource.DataSourceTransactionManager时候,要制定bean名称,例:
@Transaction(“transactionManager”)
2.spring中注解增强方式的缺点
即类中public方法不能调用本类中的其他方法,否则增强无效。
项目中由于架构设计的原因,代码构造如下所示
1 class BaseService{ 2 public void doBussiness(){ 3 …… 4 doWork(); 5 …… 6 } 7 public void doWork(){ 8 } 9 }
增加service只要继承该BaseService即可
@Transaction class ServiceImple extends BaseService{ @override public void doWork(){ …… …… } }
此时注解开启失败,经过分析原因,因为BaseService中doBussiness方法调用本类中的doWork方法时,spring并不会增强该方法,无法获得该方法的代理方法,所以无法回滚事务。
3.解决方法
所以在架构设计时要避免调用本类中抽象方法这种架构模式,这样子类继承后得不到增强。
下面提供一种手动事务管理方式
3.1有ApplicationContext 情况下
DataSourceTransactionManager transactionManager = (DataSourceTransactionManager) ctx.getBean("txManager"); DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。 TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态 try { //逻辑代码,可以写上你的逻辑处理代码 transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); }
3.2 没有ApplicationContext 情况
@Autowired //这里如果有多个Manager,要添加@Qualifier(“txManager”) private DataSourceTransactionManager txManager; DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别,开启新事务 TransactionStatus status = txManager.getTransaction(def); // 获得事务状态 try{ //逻辑代码,可以写上你的逻辑处理代码 txManager.commit(status); }catch(Exception e){ txManager.rollback(status); }
当然也可以做声明式事务处理,这里不再赘述!
over,欢迎大家指正,以便写出更高级的bug!