@Transactional(isolation = Isolation.SERIALIZABLE) 重试机制

Posted

技术标签:

【中文标题】@Transactional(isolation = Isolation.SERIALIZABLE) 重试机制【英文标题】:@Transactional(isolation = Isolation.SERIALIZABLE) retry mechanism 【发布时间】:2018-08-08 11:50:00 【问题描述】:
 @Transactional(isolation = Isolation.SERIALIZABLE)

我的 spring 项目中的几个方法都有这个注释。如果由于“序列化访问问题”而出现异常,如果我想重试特定事务,最好的方法是什么。有注释@Retryable,但对我来说如何使用它并不是很简单,以便事务将回滚,然后仅针对该特定异常重试,而仅针对其他运行时异常回滚。提前致谢。

【问题讨论】:

你有哪个数据库? 我支持预言机。代码应该适用于 10g 和 12g,因为在不同的环境中有不同的版本。 【参考方案1】:

一个简单的解决方案是有一个方法作为执行逻辑的“入口点”;它将实际逻辑委托给事务方法。通常,这样做的一个好方法是让一个类具有 Transactional 注释并完成工作,而另一个类是客户端与该委托进行交互的接口;提供一种间接形式。

private static final int MAX_RETRY = 5;
public void doWork(T... parameters) 
    doWork(0, parameters);


private void doWork(int retryLevel, T... parameters) 
    if (retryLevel == MAX_RETRY) 
        throw new MaximumRetryCountException(); //or any other exception
     else 
        try 
           //Get your Spring context through whatever method you usually use
           AppContext().getInstance().getBean(classInterestedIn.class).doTransactionalMethod(parameters);
         catch (ExceptionToRetryFor e) 
            doWork((retryLevel + 1), parameters);
        
    


@Transactional(isolation = Isolation.SERIALIZABLE)
public void doTransactionalMethod(parameters) 
    ...

请注意,您可能会遇到从同一类中的不同方法调用事务方法的问题(即调用 this.doTransactionalMethod()),因此事务方法的调用是通过 Spring 应用程序上下文进行的。这是由于 Spring AOP 包装类以参与事务语义的方式。见:Spring @Transaction method call by the method within the same class, does not work?

【讨论】:

是的,是的,肯定它不会在同一个班级工作。我看到你写了一个重试机制,但是可序列化的访问异常与普通的 JPAExceptions 有什么不同。我认为没有...... spring 已经有的 @Retryable 注释有什么问题。

以上是关于@Transactional(isolation = Isolation.SERIALIZABLE) 重试机制的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务管理中@Transactional

Spring @Transactional 具有来自不同调用源的不同隔离级别

Spring声明式事务@Transactional 详解,事务隔离级别和传播行为

@Transactional的参数意义及使用。spring中事务注解的配置情况

Spring的事务属性

Transactional事务管理操作