【问题标题】:How to catch transaction exceptions in @Async?如何在@Async 中捕获事务异常?
【发布时间】:2017-01-12 15:15:12
【问题描述】:

使用@Async 编写事务方法时,无法捕获@Transactional 异常。像ObjectOptimisticLockingFailureException,因为它们在事务提交期间被抛出方法本身之外。

例子:

public class UpdateService {
    @Autowired
    private CrudRepository<MyEntity> dao;

    //throws eg ObjectOptimisticLockingFailureException.class, cannot be caught
    @Async
    @Transactional
    public void updateEntity {
        MyEntity entity = dao.findOne(..);
        entity.setField(..);
    }
}

我知道我可以捕获@Async 异常一般如下:

@Component
public class MyHandler extends AsyncConfigurerSupport {
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            //handle
        };
    }
}

但我更愿意以不同的方式处理给定的异常,前提是它发生在 UpdateService 中。

问题:我如何在UpdateService内部捕捉它?

是唯一的机会:创建一个额外的 @Service 包装 UpdateService 并具有 try-catch 块?或者我可以做得更好吗?

【问题讨论】:

    标签: java spring spring-transactions spring-async


    【解决方案1】:

    你可以试试self-injecting 你的bean,它应该与Spring 4.3 一起工作。虽然自我注入通常不是一个好主意,但这可能是合法的用例之一。

    @Autowired
    private UpdateService self;
    
    @Transactional
    public void updateEntity() {
        MyEntity entity = dao.findOne(..);
        entity.setField(..);
    }
    
    @Async
    public void updateEntityAsync(){
        try {
           self.updateEntity();
        } catch (Exception e) {
            // handle exception
        }
    }
    

    【讨论】:

    • 如果这确实是自注入的有效用例,那可能就足够了。问题是:是吗?
    • @membersound:在我看来,它是有效的。也有可能误用它,最终得到一个 1000 行的“神级”。但是你的异常处理是特定于这个类的,为什么不把它放在这个类中。如果有人认为这是一种不好的做法,他们可以在这里发表评论......
    • 它不起作用并且失败:There is a circular dependency between 1 beans。 spring-boot.1.4.0 和 spring.4.2.3
    • @membersound:它只适用于 Spring 4.3。否则,根据链接,您可以尝试使用@Resource 并按名称注入。
    • 抱歉错字。我的意思是:spring-4.3.2,所以它应该可以工作。但没有。但我没有尝试使用@Resource,只是@Autowired。这里需要使用资源注入吗?我不想依赖资源服务名称的自动装配。还是@Autowired 仅在使用接口时才有效(我只是在使用类本身)?
    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2015-02-27
    • 2012-03-14
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多