java 多线程事务_多线程事务处理问题

代码

EquipCollectServiceImpl.java

protected static final ExecutorService handleTaskPoolExecutor = Executors.newFixedThreadPool(3);

public void queryDataToUpload(){

// 查询待上传信息

List list = equipCollectDao.queryDataByParams();

// 多线程 调用上传接口

handleTaskPoolExecutor.submit(

@Override

new Runnable(){

public void run(){

// ... 接口调用 ...

Json backInfo = {..};

// 保存接口日志(方式 1) -> 报错

interfaceDao.insertInterfaceBackLog(backInfo);

// 保存接口日志(方式 2) -> 2.1报错 2.2成功

saveInterfaceBackLog(backInfo);

// 保存接口日志(方式 3) -> 成功

interfaceService.insertInterfaceBackLog(backInfo);

}

}

);

}

@Transactional

public void saveInterfaceBackLog(Json backInfo){

// 方式 2.1

interfaceDao.insertInterfaceBackLog(backInfo);

// 方式 2.2

interfaceService.insertInterfaceBackLog(backInfo);

}

报错说明

insertInterfaceBackLog()方法中使用 查询 报:

java.util.concurrent.ExecutionException: org.hibernate.HibernateException:

Could not obtain transaction-synchronized Session for current thread

insertInterfaceBackLog()方法中使用 保存 报:

org.springframework.dao.InvalidDataAccessApiUsageException:

Write operations are not allowed in read-only mode (FlushMode.MANUAL):

Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

问题分析

查询 this.getSessionFactory().getCurrentSession() 获取不到session,然后直接报错;

保存 this.getSessionFactory().getCurrentSession() 获取不到session,会创建新session,但是FlushMode.MANUAL < FlushMode.COMMIT,然后报错;

spring-orm-4.3.4.RELEASE.jar源码如下:

if (session == null) {

session = this.getSessionFactory().openSession();

session.setFlushMode(FlushMode.MANUAL);

isNew = true;

}

总结

多线程内部不被事务控制,获取不到session,但是能够获取spring注入的bean;

多线程内部执行同类中方法,不会分配新事务(注解,AOP切面 均不生效);

方式 3,方式 2.2 每执行一次就会启动一个事务;不会影响到同线程的其他事务;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值