Mat*_*iak 0 java spring hibernate jpa spring-transactions
我有以下案例:
如何做到这一点?我不想在步骤 5 期间锁定表。步骤 1-4 的行为应类似于“SELECT FOR UPDATE”。下面是我当前的代码。我正在执行的方法是execute()。我通过从不同的应用程序实例执行它来测试它,并检查实例 A 是否能够在实例 B 执行executeJob(job)时对表执行操作。
@Service
@Slf4j
@Transactional
public class JobExecutionService {
private final Environment environment;
private final TestJobRepository testJobRepository;
private final TestJobResultRepository testJobResultRepository;
@Autowired
public JobExecutionService(Environment environment, TestJobRepository testJobRepository, TestJobResultRepository testJobResultRepository) {
this.environment = environment;
this.testJobRepository = testJobRepository;
this.testJobResultRepository = testJobResultRepository;
}
public void execute() {
TestJob job = getJob();
executeJob(job);
finishJob(job);
}
@Transactional
public TestJob getJob() {
TestJob testJob = testJobRepository.findFirstByStatusOrderByIdAsc(
0
);
testJob.setStatus(1);
testJobRepository.save(testJob);
return testJob;
}
public void executeJob(TestJob testJob) {
log.debug("Execution-0: {}", testJob.toString());
Random random = new Random();
try {
Thread.sleep(random.nextInt(3000) + 1000);
} catch (InterruptedException e) {
log.error("Error", e);
}
log.debug("Execution-1: {}", testJob.toString());
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void finishJob(TestJob testJob) {
testJobResultRepository.save(
new TestJobResult(
null,
testJob.getId(),
environment.getProperty("local.server.port")
)
);
}
}
public interface TestJobRepository extends PagingAndSortingRepository<TestJob, Long>, QueryDslPredicateExecutor<TestJob> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
TestJob findFirstByStatusOrderByIdAsc(Integer status);
}
Run Code Online (Sandbox Code Playgroud)
@Transactional私有方法在代理模式下不起作用:Spring @Transactional 属性是否在私有方法上工作?这里唯一的公共方法是execute(),因此您可以对其进行注释,也可以对整个类进行注释。
(顺便说一句,如果您制作getJob()并finishJob()公开,@Transactional仍然对它们不起作用,因为它们是从execute()方法调用的this,而不是通过事务管理基础设施生成的代理)。
您可以@Transactional从JobExecutionService、 movegetJob()和finishJob()(或应在独立事务中运行的任何方法)作为公共方法删除到新服务,例如 ,TransactionalJobExecutionService并将该新服务注释为@Transactional。
| 归档时间: |
|
| 查看次数: |
3264 次 |
| 最近记录: |