gpt4 book ai didi

java - Spring 乐观锁定 :How to retry transactional method till commit is successful

转载 作者:IT老高 更新时间:2023-10-28 13:51:02 24 4
gpt4 key购买 nike

我将 Spring 2.5 和 Hibernate JPA 实现与 Java 和“容器”托管事务一起使用。

我有一个“用户提交后”方法,它在后台更新数据,并且无论 ConcurrencyFailureExceptionStaleObjectStateException 异常如何都需要提交,因为它永远不会显示给客户。换句话说,需要把乐观锁变成悲观。 (如果方法执行需要更长的时间并且有人在其他事务中更改了数据,则可能会发生)


我读了很多关于幂等的东西,如果 search for DEFAULT_MAX_RETRIES 出现异常,请重试或 6.2.7. Examplechapter 14.5. Retry .我还在stackoverflow中找到了herehere .

我试过了:

public aspect RetryOnConcurrencyExceptionAspect {

private static final int DEFAULT_MAX_RETRIES = 20;
private int maxRetries = DEFAULT_MAX_RETRIES;

Object around(): execution( * * (..) ) && @annotation(RetryOnConcurrencyException) && @annotation(Transactional) {

int numAttempts = 0;
RuntimeException failureException = null;
do {
numAttempts++;
try {
return proceed();
}
catch( OptimisticLockingFailureException ex ) {
failureException = ex;
}
catch(ConcurrencyFailureException ex) {
failureException = ex;
}
catch( StaleObjectStateException ex) {
failureException = ex;
}
} while( numAttempts <= this.maxRetries );
throw failureException;

}
}

RetryOnConcurrencyException 是我的 Annotation,用于标记发生异常时需要重试的方法。没用...我还尝试了几种方法,例如 SELECT ... FOR UPDATEEntityManager.lock(...)

使用 Spring 避免过时数据、脏读等策略的最佳方法是什么?重试?,同步?,JPA 锁定?,隔离?,选择...进行更新?我无法让它工作,我真的很高兴能得到任何帮助。


这是我喜欢做的一些伪代码:

void doSomething(itemId) {
select something into A;
select anotherthing into B;

// XXX
item = getItemFormDB( itemId ); // takes long for one user and for other concurrent user it could take less time
item.setA(A);
item.setB(B);

// YYYY
update item;
}

在//XXX 和//YYY 之间,另一个 session 可以修改项目,然后抛出 StaleObjectStateException。

最佳答案

使用 Spring Retry当版本号或时间戳检查失败(发生乐观锁)时重试整个方法。

配置

@Configuration
@EnableRetry
public class FooConfig {
...
}

用法

@Retryable(StaleStateException.class)
@Transactional
public void doSomethingWithFoo(Long fooId){
// read your entity again before changes!
Foo foo = fooRepository.findOne(fooId);

foo.setStatus(REJECTED) // <- sample foo modification

} // commit on method end

项目配置

Spring Boot 应用已经定义了有效的 spring-retry 版本,所以只有这个是必需的:

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

关于java - Spring 乐观锁定 :How to retry transactional method till commit is successful,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3144010/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com