如何使用 @TransactionTimeout 处理事务超时。

huangapple 未分类评论55阅读模式
英文:

How to handle Transaction timeout with @TransactionTimeout

问题

我有一个方法

@TransactionTimeout(value = 1, unit = TimeUnit.SECONDS)
@Asynchronous
public void asyncMethod() {
    System.out.println("在线程 " + Thread.currentThread().getName() + " 中开始运行 asyncMethod");
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("在线程 " + Thread.currentThread().getName() + " 中完成运行 asyncMethod");
}

正如你所看到的我在事务中运行此方法超时设置为1秒方法内部有3秒的睡眠因此由于运行此方法我会得到

javax.transaction.RollbackException

但是假设我想要实现一个服务该服务将向用户打印事务超时已发生的信息我该如何实现

@Glains 在评论中给了我一些建议建议我使用拦截器

我已经添加了类似于以下的内容

@Interceptor
public class LoggingTimeoutInterceptor {

    @AroundInvoke
    public Object log(InvocationContext ctx) throws Exception {
        try {
            System.out.println("日志拦截器");
            System.out.println("方法 " + ctx.getMethod().getName());
            return ctx.proceed();
        } catch (RollbackException e) {
            System.out.println("发生事务回滚异常");
            return null;
        } catch (Exception e) {
            System.out.println("发生异常");
            return null;
        }
    }
}

这段代码会正确输出前两个sysout但是它没有捕获任何异常我不知道为什么我尝试将`@AroundInvoke`更改为`@AroundTimeout`,但那样根本不会运行
英文:

I do have method:

    @TransactionTimeout(value = 1, unit = TimeUnit.SECONDS)
	@Asynchronous
	public void asyncMethod() {
		System.out.println("start running asyncMethod in thread " + Thread.currentThread().getName());
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("finished running asyncMethod in thread " + Thread.currentThread().getName());
	}

As you can see I running this in Transaction and timeout is set to 1 second and inside I have 3 second sleep. So as a result of running this method I am gettin:

javax.transaction.RollbackException

But let say I would like to implement service which will print information that transaction timeout has occured to the user. How could I achieve that?

@Glains gave me some advice in comment to use Interceptor.

I have added something like that:

@Interceptor
public class LoggingTimeoutInterceptor {

	@AroundInvoke
	public Object log(InvocationContext ctx) throws Exception {
		try {
			System.out.println("Logger interceptor");
			System.out.println("method " + ctx.getMethod().getName());
			return ctx.proceed();
		}catch (RollbackException e) {
			System.out.println("Transaction RollbackException occured");
			return null;
		} 
		catch (Exception e) {
			System.out.println("Exception occured");
			return null;
		}
	}
}

This code is writing first two sysout correctly. But is not catching any exception and I dont know why. I was trying to change @AroundInvoke to @AroundTimeout but then it is not running at all.

huangapple
  • 本文由 发表于 2020年3月15日 20:39:43
  • 转载请务必保留本文链接:https://java.coder-hub.com/60692972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定