kevinlinxp
12/31/2016 - 8:09 AM

Java:Spring:@Scheduled,transaction

Java:Spring:@Scheduled,transaction

Soliution 1 - Manually create a transaction in a @Scheduled method

@Service
public class ServiceImpl implements Service , Serializable {
    
    //...
    
    @Qualifier("transactionManagerApp")
    private PlatformTransactionManager txMgrApp;
    
    //...
    
    @Override
    @Scheduled(cron="0 0 * * * ?")
    public void hourly()
    {
        final TransactionTemplate txTemplateApp = new TransactionTemplate(txMgrApp);
        txTemplateApp.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status)
            {
                //get xxx from dao
                dao.update(xxx);
            }
        });
    }
}

Solution 2

Make sure that your @Scheduled method makes its call to dao.update(xxx); via the Service interface, not directly on your implementation (thereby going through the proxy). Basically you need to move the @Scheduled method to another bean.

The @Transactional annotation tells Spring to wrap your original ServiceImpl bean with a dynamic proxy that also implements 'Service' (by default Spring proxies the interface, not the implementation). This proxy will transparently handle the creation and commit/rollback of the transaction when you call hourly() on the proxy. However, if you call hourly() directly on your implementation (which is what is happening above), the proxy is bypassed, so there is no transaction.