Hibernate与Spring事务管理并发处理方式

TransactionTemplate transactionTemplate;
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        SessionFactory sessionFactory = ZsCoreEnvironment.getService(SessionFactory.class);
        OpenSessionInterceptor openSessionInterceptor = new OpenSessionInterceptor();
        openSessionInterceptor.setSessionFactory(sessionFactory);
        List<CompletableFuture<Void>> futures = ListUtils.partition(applies, 40).stream().map(apps -> CompletableFuture.runAsync(() -> {
            for (long c : apps) {
                Assert.isTrue(!TransactionSynchronizationManager.hasResource(sessionFactory), "不是新线程");
                try {
                    openSessionInterceptor.invoke(new SimpleMethodInvocation() {
                        @Override
                        public Object proceed() {
                            transactionTemplate.executeWithoutResult(transactionStatus -> {
                                try {
                                    Session session = ZsCoreEnvironment.getCurrentSession();
                                    Apply apply = session.get(Apply.class, c);
                                    if (apply != null) {
                                        FlowInstance flowInstance = apply.getFlowInstance();
                                        if (flowInstance != null) {
                                            flowInstance.removeItCascade(Void.class);
                                        } else {
                                            apply.removeItCascade();
                                        }
                                    }
                                } catch (Exception e) {
                                    transactionStatus.setRollbackOnly();
                                    logger.error("删除错误", e);
                                }
                            });
                            return null;
                        }
                    });
                } catch (Throwable e) {
                    throw new RuntimeException(e);
                }
            }
        }, executorService)).toList();
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(30, TimeUnit.MINUTES);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

思路大概是以下所列:

  1. 通过Executors设置本次并发操作所用的线程模式和数量
  2. 通过org.apache.commons.collections4.ListUtils把一个待处理的集合拆分成特定大小的部份
  3. 创建CompletableFuture#runAsync 异步可返回Future实例并归集为CompletableFuture#allOf表示等待所有工作结束,你也可以根据需求换成无需返回模式Runnable方式
  4. 通过OpenSessionInterceptor拦截器打开一个Hibernate Session会话并绑定到当前事务同步管理器TransactionSynchronizationManager的上下文中
  5. 通过事务模板类TransactionTemplate 启动事务,事务粒度大小可通过逻辑控制,例子是以每一个清除(包含十几条SQL)操作一个事务,你可以多个操作一个事务,但经验法则删除事务不能包含过多
  6. 根据执行业务逻辑 ,控制事务提交还是回滚,这里不抛异常则正常提交

下面分析下OpenSessionInterceptor

public Object invoke(MethodInvocation invocation) throws Throwable {
		SessionFactory sf = getSessionFactory();
		Assert.state(sf != null, "No SessionFactory set");

		if (!TransactionSynchronizationManager.hasResource(sf)) {
			// New Session to be bound for the current method's scope...
			Session session = openSession(sf);
			try {
				TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
				return invocation.proceed();
			}
			finally {
				SessionFactoryUtils.closeSession(session);
				TransactionSynchronizationManager.unbindResource(sf);
			}
		}
		else {
			// Pre-bound Session found -> simply proceed.
			return invocation.proceed();
		}
	}

Spring事务管理器TransactionTemplate实际是HibernateTransactionManager需要在上下文中通过TransactionSynchronizationManager获取当前会话getCurrentSession创建并管理事务,所在在TransactionTemplate启动事务前必须绑定SessionHolder 通过TransactionSynchronizationManager#bindResource,最终TransactionTemplate实例负责提交事务或回滚,OenSessionInterceptor关闭session和取消当前线程unbindResource资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

victorkevin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值