Spring的Transactional注解不回滚问题

为了解决这个问题, 网上找了很多资料。
但是你懂得, 百度搜出来的都是同一个问题拷贝来拷贝去。

什么public方法,unchecked异常都试过了还是不行。

后来在谷歌上找到一个blog
https://ameblo.jp/kochablo/entry-11578714824.html

大致意思是, @Transactional必须是利用通过DI注入完后的对象调用@Transactional注释的方法。
也就是

问题代码

// ServiceA代码
public class ServiceA {
    public void insert() {
        insertTbl1();
        insertTbl2();
        //...
        //......
    }

    @Transactional
    public void insertTbl1() {
        // do something.
    }

    @Transactional
    public void insertTbl2() {
        // do something.
    }
}
// ServiceB代码
public class ServiceB {
    @Autowired
    ServiceA serviceA;

    public void test() {
        serviceA.insert();
    }
}

需要改成如下

// ServiceA代码
public class ServiceA {
    // 在ServiceB当中直接通过DI后的对象调用insert, 
    // 所以这个方法上必须要有Transactional,否则不会启动事务。
    @Transactional
    public void insert() {
        insertTbl1();
        insertTbl2();
        //...
        //......
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertTbl1() {
        // do something.
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertTbl2() {
        // do something.
    }
}
// ServiceB代码
public class ServiceB {
    @Autowired
    ServiceA serviceA;

    public void test() {
        // ServiceA的insert方法必须要@Transactional。
        serviceA.insert();
    }
}

Why?
https://dev.classmethod.jp/server-side/declarative-trasaction-by-spring-aop/

另外也可以通过代码写上事务管理也可以。

    @Autowired
    PlatformTransactionManager txManager;
    // 使用DefaultTransactionDefinition
    public void insert1() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = txManager.getTransaction(def);

        try {
            // do some thing..
            txManager.commit(status);
        } finally {
            if (!status.isCompleted()) txManager.rollback();
        }
    }

    // 使用template
    public void insert2() {
        TransactionTemplate template = new TransactionTemplate(txManager);
        template.setName("tx name");
        template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        template.execute(status -> {
            // do something... 
            return "result";
        });
    }

你可能感兴趣的:(JAVA)