【问题标题】:Spring JPA Transactional commit during process with Pessimistic lock带有悲观锁的过程中的Spring JPA事务提交
【发布时间】: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 的情况下在每批之后更新页面?

提前致谢。

【问题讨论】:

    标签: java spring-boot spring-data-jpa spring-transactions pessimistic-locking


    【解决方案1】:

    我会将@Transactional(propagation = Propagation.REQUIRES_NEW) 添加到processBatch,以便在每次迭代时提交数据(顺便说一句,savesaveAndFlush 在这种情况下工作方式相同)。

    请注意,添加此注解后,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) 之类的东西,以禁用已处理批次的回滚
    • 谢谢。但它仍然是一样的。我可以在工作期间甚至在其间终止工作之后看到更新的值。
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 2014-08-30
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多