当前位置: 首页 > news >正文

jpa多线程事务

百度都百度不到jpa多线程的事务回滚,废话少说,就是干,

实现思路(可看可不看,本人也不喜欢罗里吧嗦的,想直接看干货就跳过这里,直接执行代码):

jpa本身是不支持多线程事务,所以要手动实现事务的提交和回滚,网上可参考的太复杂,而且没用的太多,自己干吧,

首先,排除一般的影响事务回滚的条件(jpa事务失效的 场景),事务回滚的前提就是同一个连接,统一提交事务,
但是多线程,是多个实例,都不是同一个连接,自然不能统一回滚了,

实现思路:想要实现统一的管理,就要共享同一个事务,同一个connection,我们只能手动管理主线程和子线程,所以要共享EntityManager和EntityTransaction,
需要注意的是不能直接在方法外来初始化EntityManager和EntityTransaction,会报错,通过请求,再获取对象,赋值就可以了
通过内部类,来共享这两个对象,就实现了两个测试的内部类,Thread1和Thread2,
然后通过线程池,来执行多个线程,需要注意的就是,要确定子线程都执行完毕了,再提交事务,不然的话,子线程还在执行,主线程就提交了事务,多线程事务就没法生效
代码都经过测试,直接复制粘贴,代入自己数据源测试就知道了

代码实例

	/*** 注入EntityManager实例*/@Autowiredprivate EntityManagerFactory entityManagerFactory;//作为多线程的事务共享,从而统一提交或回滚,不能在这里直接createEntityManager和getTransactionEntityManager entityManager;EntityTransaction transaction;//测试方法@ResponseBody@RequestMapping(value = "/test")public RetMsgBean testThread() throws Exception {//请求的时候给实例和事务赋值entityManager = entityManagerFactory.createEntityManager();transaction = entityManager.getTransaction();try {//开始事务transaction.begin();//执行插入数据操作Query query = entityManager.createNativeQuery("insert into pt_business_logs(id) value (?)");//传入参数query.setParameter(1,"11111");//提交数据库query.executeUpdate();//创建线程池ExecutorService service= Executors.newFixedThreadPool(10);//执行事务service.execute(new Thread1());//执行事务service.execute(new Thread2());//结束线程池service.shutdown();/*** 线程没有结束,就等待500毫秒,可以随意调整等待时间,反正就是要等子线程执行完,* 不等子线程的话,子线程还在执行,主线程有可能就直接进行commit操作了,多线程事务回滚就无法生效了*/while (!service.isTerminated()) {Thread.sleep(500);System.out.println("等待子线程执行");}//事务执行完成的提示System.out.println("提交事务");//提交事务transaction.commit();} catch (Exception e) {//发生异常进行回滚,主线程的回滚不能控制子线程,只是针对主线程的异常if (transaction != null) {transaction.rollback();}e.printStackTrace();System.out.println("发生异常");}finally {entityManager.close();}//RetMsgBean无所谓,这是一个自定义的返回值类return RetMsgBean.init();}//内部类,线程1,通过继承Runnable实现
class Thread1 implements Runnable{@Overridepublic void run() {try {//执行数据库操作Query query = entityManager.createNativeQuery("insert into pt_business_logs(id) value (?)");query.setParameter(1,"222222");query.executeUpdate();//故意抛出异常System.out.println(1/0);} catch (Exception e) {e.printStackTrace();//进行回滚transaction.rollback();}}
}//内部类,线程2,通过继承Runnable实现
class Thread2 implements Runnable{@Overridepublic void run() {try {Query query = entityManager.createNativeQuery("insert into pt_business_logs(id) value (?)");query.setParameter(1,"333333");query.executeUpdate();} catch (Exception e) {e.printStackTrace();transaction.rollback();}}
}
http://www.lryc.cn/news/68640.html

相关文章:

  • 加密解密软件VMProtect教程(四):准备项目之SDK功能
  • 夏令营教育小程序开发功能和优势有哪些?
  • Cocos CreatorXR 1.2.0 今日发布,正式支持 WebXR ,并开启 MR 之路
  • Linux 使用笔记(本人出品,必属精品)
  • 【2023 · CANN训练营第一季】初识新一代开发者套件 Atlas 200I DK A2 第二章——安装Atlas 200I DK A2跑通第一个案例
  • concurrenthashmap
  • 8年测试总结,项目/团队如何做自动化测试?效率价值?吐血整理...
  • 图像动态裁剪
  • Thematica: 炫彩主题与黑暗奇观的Vue3之旅
  • 平凡的Python为什么能一跃成为世界排名第一的语言
  • Wijmo 2023 v1 Crack
  • 万物互联时代的边缘计算安全需求与挑战
  • 函数序列与函数项级数
  • UML时序图详解
  • Centos7.6部署postgresql15主从
  • 【ThinkPHP6系列学习-2】多应用模式配置
  • Linux内核oops panic简析
  • Spark大数据处理讲课笔记4.8 Spark SQL典型案例
  • WhatsApp Business 多人使用终极指南
  • 布局和视图的常用属性
  • 解说天下之操作系统
  • Pruning 系列 (八)layer常用简枝(torch)方法
  • Gigabyte Z490 Vision D i9-10900k电脑 Hackintosh 黑苹果efi引导文件
  • UWB智慧工厂人员定位系统源码,人员在岗监控、车辆实时轨迹监控源码
  • 从认识元注解到使用元注解
  • 【C++从0到王者】第六站:类和对象(下)
  • AJax和Axios的讲解
  • 企业落地数字化转型,如何部署战略规划
  • 新的网络钓鱼即服务平台让网络犯罪分子生成令人信服的网络钓鱼页面
  • MySQL的隐式转换