Java 在Restful应用程序中拦截异步调用的乐观锁定后的@Transactional
我今天的问题是@Transactional注释导致乐观锁异常(OLE)并回滚事务后如何重试方法 我有一个对Restful应用程序的异步调用,该应用程序正试图根据某些业务逻辑更新数据库对象。如果获得OLE,我希望在延迟0.2-0.5秒后重试事务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(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的更多详细信息,请参阅