问题描述
限时送ChatGPT账号..我今天的问题是在@Transactional注解导致乐观锁异常(OLE)并回滚事务后如何重试方法.
The question I have today is how to retry a method after the @Transactional annotation causes an Optimistic Lock Exception (OLE) and rolls back the transaction.
我对 Restful 应用程序进行了异步调用,该应用程序尝试根据某些业务逻辑更新数据库对象.如果我得到一个 OLE,我想在 0.2-0.5 秒的延迟后重试该事务.
I have asynchronous calls to a Restful application that are attempting to update a database object based on some business logic. If I get an OLE, I'd like to retry the transaction after a delay of 0.2-0.5 seconds.
@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();
}
我尝试使用 AspectJ 在抛出 OLE 后拦截我的方法,以便我可以重试.但是,问题是@Transactional 注释.我的方法是不抛出错误消息,因为业务逻辑没有失败.相反,myMethod 返回 200 响应,但遇到 OLE 异常,然后在负责调用 myMethod 的 ResourceJavaMethodDispatcher.java 类中抛出.
I've tried using AspectJ to intercept my method after it throws the OLE so that I can retry. However, the issue is the @Transactional annotation. My method is not throwing the error message since business logic is not failing. Instead, myMethod returns a 200 response, but the OLE exception is encountered and then thrown in the ResourceJavaMethodDispatcher.java class that is responsible for invoking myMethod.
我的方面类:
@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() 方法具有在线程上调用等待然后重试最多三次尝试的逻辑.
The invokeAndRetry() method has the logic to call wait on the thread and then retry up to a maximum of three tries.
我可以从业务逻辑抛出的异常成功进入myAspect;但是从事务中抛出的 OLE 没有被 myAspect 捕获.
I can successfully get into myAspect from an exception thrown by business logic; but the OLE thrown from the transaction does not get caught in myAspect.
说了这么多,有没有办法包装/封装/拦截@Transaction注解来运行我的重试逻辑?
Having said all of that, is there a way to wrap/encapsulate/intercept the @Transaction annotation in order to run my retry logic?
附注:
1) 我已经研究过基于示例创建我自己的 @Retry 注释 此处.我已经使用该依赖项尝试了他的 @Retry 注释,但无济于事.
1) I've looked into creating my own @Retry annotation based on the example here. I've used that dependency to try his @Retry annotation, but to no avail.
2) 我将研究 Spring 的 @within,看看它是否有用.
2) I'll be looking into Spring's @within to see if that could prove useful.
推荐答案
在做了一些研究并查看了更多教程之后,我找到了一种让我的方面优先于 @Transactional 的方法.在@Aspect 标记下方,我添加了注释@Order(1).
After doing some research and looking at some more tutorials, I found a way to have my aspect take precedence over @Transactional. Just below the @Aspect tag, I added the annotation @Order(1).
这使我的方面具有更高的优先级,因为 @Transactional 默认为 Ordered.LOWEST_PRECEDENCE.请参阅 Spring 文档有关@Order 的更多详细信息.
This gives my aspect higher priority since @Transactional is defaulted to Ordered.LOWEST_PRECEDENCE. See Spring documentation for some more details about @Order.
这篇关于Restful App异步调用乐观锁后拦截@Transactional的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论