湖北海厦建设有限公司网站,建设网站多久到账,徐家汇网站建设,广州 网站建设网络推广网页设计百度都百度不到jpa多线程的事务回滚#xff0c;废话少说#xff0c;就是干#xff0c;
实现思路#xff08;可看可不看#xff0c;本人也不喜欢罗里吧嗦的#xff0c;想直接看干货就跳过这里#xff0c;直接执行代码#xff09;#xff1a; jpa本身是不支持多线程事务…百度都百度不到jpa多线程的事务回滚废话少说就是干
实现思路可看可不看本人也不喜欢罗里吧嗦的想直接看干货就跳过这里直接执行代码 jpa本身是不支持多线程事务所以要手动实现事务的提交和回滚网上可参考的太复杂而且没用的太多自己干吧 首先排除一般的影响事务回滚的条件(jpa事务失效的 场景)事务回滚的前提就是同一个连接统一提交事务 但是多线程是多个实例都不是同一个连接自然不能统一回滚了 实现思路想要实现统一的管理就要共享同一个事务同一个connection,我们只能手动管理主线程和子线程所以要共享EntityManager和EntityTransaction 需要注意的是不能直接在方法外来初始化EntityManager和EntityTransaction会报错通过请求再获取对象赋值就可以了 通过内部类来共享这两个对象就实现了两个测试的内部类Thread1和Thread2 然后通过线程池来执行多个线程需要注意的就是要确定子线程都执行完毕了再提交事务不然的话子线程还在执行主线程就提交了事务多线程事务就没法生效 代码都经过测试直接复制粘贴代入自己数据源测试就知道了 代码实例 /*** 注入EntityManager实例*/Autowiredprivate EntityManagerFactory entityManagerFactory;//作为多线程的事务共享从而统一提交或回滚不能在这里直接createEntityManager和getTransactionEntityManager entityManager;EntityTransaction transaction;//测试方法ResponseBodyRequestMapping(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();}}
}