spring添加@Transcational的事务调度问题

Posted icanner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring添加@Transcational的事务调度问题相关的知识,希望对你有一定的参考价值。

报错信息:org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 服务器无法继续执行该事务。说明: 8900000003。

xml代码如下:

 <task:scheduler id="scheduler" pool-size="5"/>
    <task:scheduled-tasks scheduler="scheduler">
        <!--BOM库龄每间隔1分钟执行-->
        <task:scheduled ref="amsJob" method="eglInventoryAgingBom" fixed-delay="10000"/>
        <!--RFID库龄每间隔1分钟执行-->
        <task:scheduled ref="amsJob" method="eglInventoryAgingRfid" fixed-delay="10000"/>
        <!-- 日库存,每隔一天执行 -->
        <task:scheduled ref="amsJob" method="dailyItrn" cron="0 0 1 * * ?"/>
</task:scheduled-tasks>

amsJob.java文件代码如下:

@Service
public class AmsJob {

    @Resource
    private InventoryBomAgingMapper inventoryBomAgingMapper;
    @Resource
    private InventoryRfidAgingMapper inventoryRfidAgingMapper;
     //当在此处添加事务时报错
    @Transactional
    public void eglInventoryAgingBom() {
        inventoryBomAgingMapper.eglInventoryAgingBom();
    }

    @Transactional
    public void eglInventoryAgingRfid() {
        inventoryRfidAgingMapper.eglInventoryAgingRfid();
    }
    
}

报错原因:不能为这个事务打开JDBC连接,任务调度每10秒钟执行一次,当执行第一次时,拿到第一次连接,给这个连接加上了Transcational,当第二次再去连接池取时,可能会拿到同一个连接,并且还带上了第一次的Transcational,但是第二次本身有自己的Transcational,因此报错.

解决方案:采取折中的办法,新建一个Service类,在service类中添加事务,amsJob去调用service中的方法.

解决方案代码如下:

amsJob.java文件代码做如下修改:

@Service
public class AmsJob {
    // 在此处注入一个Service,在这个Service里添加事务
    @Resource
    private JobService jobService;
   
     //在此处把事务给去掉
    public void eglInventoryAgingBom() {
        jobService.eglInventoryAgingBom();
    }

    public void eglInventoryAgingRfid() {
        jobService.eglInventoryAgingRfid();
    }
    
}

新增JobService类:

@Service
public class JobService {
    
    @Resource
    private InventoryBomAgingMapper inventoryBomAgingMapper;
    @Resource
    private InventoryRfidAgingMapper inventoryRfidAgingMapper;
    //事务在此处开启
    @Transactional
    public void eglInventoryAgingBom() {
        inventoryBomAgingMapper.eglInventoryAgingBom();
    }

    @Transactional
    public void eglInventoryAgingRfid() {
        inventoryRfidAgingMapper.eglInventoryAgingRfid();
    }

}

如此一来,大功告成,皆大欢喜.

以上是关于spring添加@Transcational的事务调度问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring源码剖析-事务源码之@Transactionl解析

parallelStream与Spring事务相遇?不是冤家不聚头~

parallelStream与Spring事务相遇?不是冤家不聚头~

SpringSpringMVCJPA集成

Spring添加声明式事务

添加 Spring 事务时三重关联的持久性