我有如下的交易,
@Transactional
public void changeJobStatus(Long jobId){
JobEntity jobEntity = jobRepository.findOneForUpdate(jobId);
...
}
findOneForUpdate是用悲观锁定查找数据库,
public interface JobRepository extends CrudRepository<JobEntity, Long>{
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select j from JobEntity j where j.id = :id")
JobEntity findOneForUpdate(@Param("id") Long id);
}
如果我正常调用 changeJobStatus ,这很有效。
但是在调用下面的TimerTask时,
TimerTask task = new TimerTask() {
@Override
public void run() {
changeJobStatus(jobId);
}
};
timer.schedule(task, waitTime);
会有例外:
javax.persistence.TransactionRequiredException: no transaction is in progress
为什么会这样?如果有办法在TimerTask中调用事务?
答案 0 :(得分:1)
对changeJobStatus()
的调用实际上直接指向你的bean(自调用),因此在bean之间调用时不受通常的Spring代理约束。因此,没有任何交易开始。
请参阅:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-declarative-annotations搜索&#34;自我调用&#34;。
可能有几种可能的方法来解决这个问题:
我的方法取决于这是孤立的还是常见的情况。如果常见,我会调查&#34; aspectj&#34;模式;但我可能希望它是一个异常值,我可以坚持标准的Spring&#34;代理&#34;模式。
答案 1 :(得分:0)
这是由Spring的AOP限制造成的。正如Thomas建议的那样,手动控制事务可以解决这个问题,而不是使用@Transactional。这是详细实现,
我创建了一个简单的交易服务,如下所示,
@Service
public class SimpleTransactionService {
private final TransactionTemplate transactionTemplate;
@Autowired
public SimpleTransactionService(PlatformTransactionManager transactionManager){
transactionTemplate = new TransactionTemplate(transactionManager);
}
public void executeTransaction(ITransactionService task){
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
task.transactionExecute();
}
});
}
}
ITransactionService只是一个带有一个方法的简单接口,
public interface ITransactionService {
void transactionExecute();
}
以下是我在TimerTask中使用的方法,
public void addTimerTask(Object param, Long waitTime){
TimerTask task = new TimerTask() {
@Override
public void run() {
simpleTransactionService.executeTransaction(() -> someOperation(param));
}
};
timer.schedule(task, waitTime);
}
someOperation 是执行的实际交易。使用简单的事务服务和lambda,可以在没有任何注释的情况下完成事务。