记一次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!

posted @ 2018-11-27 22:11  superChong  阅读(512)  评论(0编辑  收藏  举报