多线程插入数据开启事务,要么都成功要么都失败,PlatformTransactionManager 管理事务

spring为我们提供了事务相关的接口,PlatformTransactionManager 

public interface PlatformTransactionManager extends TransactionManager {

   // 获取当前活动的事务或创建一个新事务
   TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
         throws TransactionException;

   // 提交事务
   void commit(TransactionStatus status) throws TransactionException;

   // 回滚事务
   void rollback(TransactionStatus status) throws TransactionException;

}

 项目代码(copy下来, 供参考)

Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(() -> {
            try {
                Map<String, Object> map = redisUtil.hmEntries(RedisKey.event);
                if (!map.isEmpty()) {
                    
                    // 先在开启多线程外面,定义一个同步集合:
                    List<TransactionStatus> transactionStatuses = Collections.synchronizedList(new ArrayList<>());

                    List<EventObject> objectList = CacheUtil.mapValueToList(map, EventObject.class);
                    List<List<EventObject>> lists = ListUtils.cut(objectList, (int) Math.ceil((double) objectList.size() / threadPoolSize));
                    // 出错标识
                    AtomicBoolean error = new AtomicBoolean(false);
                    lists.forEach(l -> {
                        executor.execute(() -> {
                            try {
                                // 开启事务
                                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                                TransactionStatus status = platformTransactionManager.getTransaction(def);
                                transactionStatuses.add(status);

                                // 保存事件
                                boolean r = eventService.saveBatch(new ArrayList<>(l));
                                log.info("保存事件:[{}]", r);
                                ArrayList<TServiceEventData> eventNumList = new ArrayList<>();
                                ArrayList<EventNumDTO> eventNumDTOS = new ArrayList<>();

                                for (EventObject object : l) {
                                    TServiceEventData eventData = JSON.parseObject(JSON.toJSONString(object.getEventData()), TServiceEventData.class);
                                    eventData.setServiceEventId(object.getId());
                                    eventNumList.add(eventData);

                                    // 事件数量
                                    EventNumDTO eventNumDTO = new EventNumDTO();
                                    eventNumDTO.setAppId(Long.valueOf(object.getAppId()));
                                    eventNumDTO.setServiceId(Long.valueOf(object.getServiceId()));
                                    eventNumDTOS.add(eventNumDTO);
                                }
                                // 保存事件数量
                                boolean r2 = eventDataService.saveBatch(eventNumList);
                                log.info("保存事件数量: [{}]", r2);

                                boolean b = updateOrInsertList(eventNumDTOS);
                                log.info("更新事件结果:{}", b);
                            } catch (TransactionException e) {
                                e.printStackTrace();
                                error.set(true);
                            }
                        });
                    });
                    // 如果出错回滚事务
                    if (error.get()) {
                        transactionStatuses.forEach(status -> platformTransactionManager.rollback(status));
                    } else {
                        transactionStatuses.forEach(status -> platformTransactionManager.commit(status));
                        Set<String> keySet = map.keySet();
                        keySet.forEach(key -> redisUtil.hmDelete(RedisKey.event, key));
                    }
                }
            } catch (Exception e) {
                log.error("保存处理event定时任务异常,{}", e.getMessage());
            }
        }, 1, delay, unit);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值