Java 在Restful应用程序中拦截异步调用的乐观锁定后的@Transactional

Java 在Restful应用程序中拦截异步调用的乐观锁定后的@Transactional,java,spring,transactions,spring-aop,optimistic-locking,Java,Spring,Transactions,Spring Aop,Optimistic Locking,我今天的问题是@Transactional注释导致乐观锁异常(OLE)并回滚事务后如何重试方法 我有一个对Restful应用程序的异步调用,该应用程序正试图根据某些业务逻辑更新数据库对象。如果获得OLE,我希望在延迟0.2-0.5秒后重试事务 @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED, readOnly = false) public Response myMethod(Lon

我今天的问题是@Transactional注释导致乐观锁异常(OLE)并回滚事务后如何重试方法

我有一个对Restful应用程序的异步调用,该应用程序正试图根据某些业务逻辑更新数据库对象。如果获得OLE,我希望在延迟0.2-0.5秒后重试事务

@Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED, readOnly = false)
public Response myMethod(Long myParam) throws Exception {
    ~Call to update db using hibernate after business logic~;
    return Response.ok().build();
}
我尝试在抛出OLE后使用AspectJ拦截我的方法,以便重试。但是,问题在于@Transactional注释。我的方法不是抛出错误消息,因为业务逻辑没有失败。相反,myMethod返回一个200响应,但是遇到OLE异常,然后抛出到负责调用myMethod的ResourceJavaMethodDispatcher.java类中

我的方面类:

@Aspect
public class myAspect {

    @AfterThrowing(value = "execution(* com.package.blah.myClass.myMethod(..)) && args(.., myParam)", throwing = "ex")
    public Response catchAndRetry(JoinPoint jp, Throwable ex, Long myParam) throws Throwable {

        Response response = null; 

        response = invokeAndRetry(jp, myParam);

        return response;
    }
}
invokeAndRetry()方法的逻辑是调用线程上的wait,然后最多重试三次

我可以从业务逻辑引发的异常成功地进入myAspect;但是从事务中抛出的OLE不会在myAspect中被捕获

说到这里,有没有办法包装/封装/截取@Transaction注释以运行我的重试逻辑

旁注:

1) 我已经考虑过根据这个例子创建自己的@Retry注释。我曾使用该依赖项尝试他的@Retry注释,但没有任何效果


2) 我将研究Spring的@In,看看它是否有用。

简短的回答是:在异常发生后,您不应该尝试重用
EntityManager
。根据最可能适用于所有JPA提供商的:

如果
EntityManager
抛出异常(包括任何
SQLException
),您应该立即回滚数据库事务,调用
EntityManager.close()
(如果调用了
createEntityManager()
)并放弃
EntityManager
实例。
EntityManager
的某些方法不会使持久性上下文保持一致状态。实体管理器引发的任何异常都不能视为可恢复的。通过在finally块中调用
close()
,确保将关闭
EntityManager
。请注意,容器管理的实体管理器将为您执行此操作。您只需让
RuntimeException
传播到容器


不过,您可能可以使用
EntityManager的新实例在新事务中执行重试操作,但这是一个不同的用例。

在做了一些研究并查看了更多教程后,我找到了一种方法,使我的方面优先于@Transactional。就在@Aspect标记的下方,我添加了注释@Order(1)

这使我的方面具有更高的优先级,因为@Transactional默认为Ordered.lower_优先级。有关@Order的更多详细信息,请参阅