You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JEE @Transactional注解:rollbackOn/dontRollbackOn指定位置咨询

Understanding @Transactional(dontRollbackOn) Placement in JEE

Great question—this is a common point of confusion with transactional annotations, so let's break it down with clear rules and examples.

First, the core principle: Transactional rollback rules (like dontRollbackOn or rollbackOn) are defined by the annotation on the method that starts the transaction, not the method that throws the exception. Once a transaction context is established, its rules "stick" with that context for all subsequent method calls that participate in it (unless a new transaction is explicitly started).

Let's walk through your two proposed scenarios:

1. Adding dontRollbackOn to the class/method that throws the exception

This only works if that method is the one initiating the transaction. For example, if the exception-throwing method has @Transactional(propagation = Propagation.REQUIRES_NEW) (or uses the default REQUIRED when no existing transaction exists), then its dontRollbackOn rule will govern the transaction it starts.

But if the exception-throwing method is called from within an existing transaction context (i.e., it joins an ongoing transaction), its dontRollbackOn setting will be ignored. The original transaction's rules, defined by the method that started it, take precedence.

2. Adding dontRollbackOn to the method that creates the transaction (using REQUIRES_NEW)

This is the correct approach for your scenario. When you use propagation = Propagation.REQUIRES_NEW, that method explicitly starts a brand-new, independent transaction. The dontRollbackOn (or rollbackOn) values you set here define the rules for this new transaction—any exceptions thrown within this transaction's scope (even from other classes/methods) will be evaluated against these rules.

Think of it like this: the transaction's rules are set in stone when the transaction is created. Any method that joins this transaction follows those rules, regardless of their own annotations (unless they start their own new transaction with different rules).

Example Code

Here's a concrete illustration:

// Service that starts a new transaction with custom rollback rules
@Service
public class TransactionInitiatingService {

    @Autowired
    private ExceptionThrowingService exceptionThrowingService;

    // This method creates a new transaction and defines its rollback rules
    @Transactional(propagation = Propagation.REQUIRES_NEW, dontRollbackOn = {SomeRuntimeException.class})
    public void executeTransactionalWork() {
        // Do some database operations here...
        
        // Call a method that throws the exception we want to ignore for rollback
        exceptionThrowingService.triggerSomeRuntimeException();
        
        // Even after the exception is thrown, this transaction will NOT rollback
        // because we defined dontRollbackOn on the transaction-initiating method
    }
}

// Service that throws the exception (no transactional annotation needed here)
@Service
public class ExceptionThrowingService {
    public void triggerSomeRuntimeException() {
        throw new SomeRuntimeException("Intentional exception that won't trigger rollback");
    }
}

Key Takeaway

If you want a specific exception to not trigger a rollback for a transaction, you must define dontRollbackOn on the method that starts that transaction. The "sticky" behavior you mentioned is exactly how JEE transactions work—once the transaction is created with its rules, those rules apply to all activity within that transaction context.

内容的提问来源于stack exchange,提问作者Lonzak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:35:31