Restful App异步调用乐观锁后拦截@Transactional [英] Intercepting @Transactional After Optimistic Lock for Asynchronous Calls in Restful App

查看:39
本文介绍了Restful App异步调用乐观锁后拦截@Transactional的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天的问题是在@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆