Spring事务-noRollbackFor在发生异常时不会提交
我希望如果我收到电子邮件异常,不要回滚事务。
我正在使用 HibernateTransactionManager ,
set property name="nestedTransactionAllowed" value="true"
因为我有嵌套事务。
另外,因为我调用 this.getService()
我设置了
lookup-method name="getService" bean="enrollmentProcessorService"
。
这样我应该得到 Spring 代理。
但如果发生异常,事务仍然会回滚。 我的代码如下所示:
@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void processConfirmation() throws SystemException {
//do something
this.getService().processConfirmationData(as400ContractId);
}
@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})
public void processConfirmationData(final long as400ContractDataId) throws SystemException {
final AS400ContractData as400ContractData = this.readAS400ContractData(as400ContractDataId, false);
this.populateEnrollmentOptionAnswers(as400ContractData.getContractData());
final PersonalData personalData = this.readPersonalData(as400ContractData.getContractData()
.getEpiphanyPersonalData().getPersonalData().getId(), true);
try {
personalData.setConfirmMailSent(true);
as400ContractData.getContractData().getEpiphanyPersonalData().getPersonalData().setConfirmMailSent(true);
this.personalDataDAO.flush();
this.emailService.sendConfirmationMailToLOI(as400ContractData); //commit if exception is thrown here
} catch (final DataAccessException dae) {
LOGGER.error(CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
throw new SystemException(StringUtils.EMPTY, CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
} catch (final MessagingException e) {
LOGGER.error(CANNOT_SEND_CONFIRMATION_EMAIL, e);
throw new SystemException(StringUtils.EMPTY, CANNOT_SEND_CONFIRMATION_EMAIL, e);
} catch (final MailException e) {
Throwable rootCause = e.getRootCause();
System.out.println("caught");
I want that if i get an E-Mail Exception, to NOT rollback the transaction.
I am using HibernateTransactionManager
and
set property name="nestedTransactionAllowed" value="true"
because i have nested transactions.
Also because i call this.getService()
i have set
lookup-method name="getService" bean="enrollmentProcessorService"
.
This way i should get the Spring Proxy.
But if exceptions occurs, the transaction is still rolledback.
my code looks like this:
@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void processConfirmation() throws SystemException {
//do something
this.getService().processConfirmationData(as400ContractId);
}
@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})
public void processConfirmationData(final long as400ContractDataId) throws SystemException {
final AS400ContractData as400ContractData = this.readAS400ContractData(as400ContractDataId, false);
this.populateEnrollmentOptionAnswers(as400ContractData.getContractData());
final PersonalData personalData = this.readPersonalData(as400ContractData.getContractData()
.getEpiphanyPersonalData().getPersonalData().getId(), true);
try {
personalData.setConfirmMailSent(true);
as400ContractData.getContractData().getEpiphanyPersonalData().getPersonalData().setConfirmMailSent(true);
this.personalDataDAO.flush();
this.emailService.sendConfirmationMailToLOI(as400ContractData); //commit if exception is thrown here
} catch (final DataAccessException dae) {
LOGGER.error(CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
throw new SystemException(StringUtils.EMPTY, CANNOT_UPDATE_PERSONAL_DATA_OBJECT, dae);
} catch (final MessagingException e) {
LOGGER.error(CANNOT_SEND_CONFIRMATION_EMAIL, e);
throw new SystemException(StringUtils.EMPTY, CANNOT_SEND_CONFIRMATION_EMAIL, e);
} catch (final MailException e) {
Throwable rootCause = e.getRootCause();
System.out.println("caught");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,您捕获异常,因此 Spring 拦截器无法看到它并回滚事务。
然后,即使您没有捕获它,您也已使用
**no**RollbackFor = {MailException.class}
配置了该方法。这意味着如果抛出此异常,您不想要回滚。请改用rollbackFor = {MailException.class}。First, you catch the exception, so there is no way the Spring interceptor can see it and rollback the transaction.
And then, even if you didn't catch it, you've configured the method with
**no**RollbackFor = {MailException.class}
. This means that you don't want a rollback if this exception is thrown. UserollbackFor = {MailException.class}
instead.每当出现异常时,当前事务就会回滚。无回滚规则,适用于您不希望在引发异常时将事务标记为回滚的情况。尝试删除 noRollbackFor 注释。
您还应该重新抛出异常。不要捕获 MailException。
Whenever you get exception, current transaction is rollbacked. No rollback rules, for those times when you do not want a transaction to be marked for rollback when an exception is thrown. Try to remove noRollbackFor annotation.
Also you should rethrow exception. Don't catch MailException.
昨天,我遇到了同样的问题。
当我看到来源:org.springframework.transaction.interceptor.TransactionInterceptor#invoke。
我发现问题出在哪里了。
this.emailService.sendConfirmationMailToLOI 是另一个服务,因此 TransactionAttribute 是新的。
你可以解决这个问题:
@Transactional(传播 = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})
在这个方法中(emailService.sendConfirmationMailToLOI*),上面的配置
Yesterday, I encountered the same problem.
When I saw the source :org.springframework.transaction.interceptor.TransactionInterceptor#invoke.
I found where the problem is.
this.emailService.sendConfirmationMailToLOI is another Service, so the TransactionAttribute is new.
you can fix this problem :
@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = {MailException.class})
In this method(emailService.sendConfirmationMailToLOI*), the configuration above