尽管抛出异常,但事务没有回滚

Transaction is not getting rolled back though exception is thrown

目前,我们的应用程序面临 spring 交易相关问题。 如您所见,在 deleteRecord() 中我们正在执行数据库操作。但在下一行 抛出业务异常。

预期行为(据我所知): 应该回滚数据库操作,因为从下一行

抛出异常

实际行为: 它不会回滚。正在将数据插入 table

问题: 为什么交易没有回滚?我不认为这是因为 catch 块 因为 deleteRecord() 将在新事务中执行。如有错误请指正

代码:

class A {
    void myMethod() {
        for(int i=0 ; i<count ; i++) {
            try {
                    deleteRecord();
                } catch(Exception e) {
                    log.error("Exception caught");

                }

        }

}

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    deleteRecord() throws Exception{
        line 1 : deleting record 
        line 2 : Throwing business exception 

    }
}

改为

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

Spring 文档说明如下:

While the EJB default behavior is for the EJB container to automatically roll back the transaction on a system exception (usually a runtime exception), EJB CMT does not roll back the transaction automatically on an application exception (that is, a checked exception other than java.rmi.RemoteException). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this.

In its default configuration, the Spring Framework’s transaction infrastructure code only marks a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. ( Errors will also - by default - result in a rollback). Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration

见 16.5.3:https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html

这表示事务的默认行为只会回滚 RuntimeExceptions。如果您有自己的业务异常(可能是已检查的异常),您必须明确命名异常 class 事务应回滚:

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = YOUREXCEPTION.class)

这是因为@Transaction 方法被同一个class 中的方法调用,如果你没有配置Spring 使用AspectJ 是不起作用的。

Spring @Transaction 方法调用同class内的方法,不起作用?