带有悲观锁的过程中的Spring JPA事务提交
Posted
技术标签:
【中文标题】带有悲观锁的过程中的Spring JPA事务提交【英文标题】:Spring JPA Transactional commit during process with Pessimistic lock 【发布时间】:2022-01-17 22:30:54 【问题描述】:我需要使用悲观锁执行批处理操作,以便在此操作期间没有其他人可以读取或写入该行。但是我想在每批之后增加页码,这样如果事务失败或实例死亡,我将从最后一页继续。但是使用下面的代码,在所有批次完成之前它不会更新页面,因此在重新启动作业时,它从 page=0 开始处理。
@Transactional
public void process(long id)
Entity entity = repo.findById(id);
processBatch(entity);
void processBatch(Entity entity)
int totalPages = otherMicroService.getTotalPages(id);
int lastPage = entity.getPage();
for(int page=lastPage; i<totalPages; i++)
doOperation();
entity.setPage(page);
repo.save(entity);
@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Entity> findById(int id);
有没有办法在启用 PESSIMISTIC_WRITE 的情况下在每批之后更新页面?
提前致谢。
【问题讨论】:
【参考方案1】:我会将@Transactional(propagation = Propagation.REQUIRES_NEW)
添加到processBatch
,以便在每次迭代时提交数据(顺便说一句,save
和saveAndFlush
在这种情况下工作方式相同)。
请注意,添加此注解后,processBatch
方法需要移动到单独的 bean(或应进行 bean 的自注入),以使 Spring AOP 正常工作。
【讨论】:
你的意思是@Transactional on process() 和@Transactional(propagation = Propagation.REQUIRES_NEW) on processesBatch(),两个注解? @Lock(LockModeType.PESSIMISTIC_WRITE) 不会阻止新事务的写入吗? 试过了。仍然没有发生更新。我相信这是因为锁定:@Lock(LockModeType.PESSIMISTIC_WRITE)。解决这个问题的任何替代方法! 抱歉,我的意思是使用“REQUIRES_NEW”方法将“for”语句中的内部代码提取到单独的 bean。此外,您可能需要为外部方法设置@Transaction(noRollbackFor=Exception.class)
之类的东西,以禁用已处理批次的回滚
谢谢。但它仍然是一样的。我可以在工作期间甚至在其间终止工作之后看到更新的值。以上是关于带有悲观锁的过程中的Spring JPA事务提交的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA / Hibernate中锁的范围是什么?