Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot transaction cannot work in timer

I have a transaction like below,

@Transactional
public void changeJobStatus(Long jobId){
    JobEntity jobEntity = jobRepository.findOneForUpdate(jobId);
    ...
}

And findOneForUpdate is to lookup database with pessimistic lock,

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);
}

This works well, if I call changeJobStatus normally.

But when calling in a TimerTask like below,

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            changeJobStatus(jobId);
        }
    };
    timer.schedule(task, waitTime);

there would be an exception:

javax.persistence.TransactionRequiredException: no transaction is in progress

Why this happens? And if there is a way to call transaction in a TimerTask?

like image 563
Man Shen Avatar asked Sep 19 '25 15:09

Man Shen


1 Answers

The call to changeJobStatus() is effectively direct to your bean (self-invocation), and therefore not subject to the usual Spring proxying when calling between beans. For this reason no transaction is getting started.

See: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-declarative-annotations search for "self-invocation".

There may be several potential ways to approach this:

  1. You could auto-wire a reference to your own bean, which would be fulfilled with a proxy, and call thru that;
  2. You could use mode="aspectj", which performs bytecode weaving (enhancement).
  3. You could control the transaction manually via PlatformTransactionManager;

My approach would depend on whether this is isolated, or a common case. If common, I'd investigate "aspectj" mode; but I would probably hope that it were an outlier and I could stick to the standard Spring "proxy" mode.

like image 190
Thomas W Avatar answered Sep 21 '25 03:09

Thomas W