SpringBoot处理内外事务及线程ID使用

1.SpringBoot处理内外事务

   场景如下:

        某个接口,内部会调用其他多个接口,这些接口属于同一个事务下,统一回滚或提交,在出异常的情况下,需要修改其他数据的订单状态,所以事务的一致性是不能保证的,需要对事务级别进行限制

  解决方式:

      1.设置独立事务,给同一事务下的方法设置自己的独立事务,自己提交或者回滚,不知道啥问题,楼主测试后无效

@Transactional(propagation = Propagation.REQUIRES_NEW)

      2.手动处理事务(类似于独立事务,出现异常手动回滚,外部不会接收异常,返回相应code码或者状态判断即可)

    //第一步注入事务数据管理器
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;

    //第二步声明并创建DefaultTransactionDefinition类,该类为TransactionDefinition的子类,很多人都说直接注入TransactionDefinition类,经测试无效,猜想是事务级别的原因
    //此处声明DefaultTransactionDefinition类
    DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
    //很重要的一点,设置事务的级别,可以查看源码来得知独立事务的级别并设置        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
    //传入事务管理器
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);

    //第三步,在需要手动管理事务的地方提交或者回滚
    //回滚
    dataSourceTransactionManager.rollback(transactionStatus);
    //提交 
    dataSourceTransactionManager.commit(transactionStatus);

         这里需要说明的是,手动触发事务后,外部try{}catch{}是无法捕捉异常的,可以自定义返回码或者状态在外面判断,然后在外面处理自己想处理的其他数据.

     

2.线程ID的使用

   在我的springboot记录日志博文中,有一个严重错误,就是定义的json是全局的,导致数据会出现错乱的现象,但是拦截器和过滤器之间想要进行数据间的交互,我这里采用的是获取线程ID的形式进行辨别

//获取线程ID
Thread.currentThread().getId();
//获取线程名称
Thread.currentThread().getName();

  因为线程的特性,在请求未结束前,线程ID是不会被占用和复用的,这样在请求日志中可以在redis中用线程ID作为key进行数据存储,在过滤器中获取响应数据,然后通过线程ID获取缓存数据再次更新,等待操作结束存入静态集合后,删除该缓存即可

   

//获取返回值
        byte[] content = responseWrapper.getContent();
        //判断是否有值
        if (content.length > 0) {
            String str = new String(content, "UTF-8");
            ServletOutputStream out = response.getOutputStream();
            out.write(content);
            out.flush();
            JSONObject endJson = (JSONObject) redisService.get(Thread.currentThread().getName());
            System.out.println(Thread.currentThread().getName());
            if(!endJson.getString(URI).contains(DOWMLOAD_FILE)){
                endJson.put("response",str);
                redisService.put(Thread.currentThread().getName(),endJson,timeout);
                JSONObject endJsons = (JSONObject) redisService.get(Thread.currentThread().getName());
                logProcess.addData(endJsons);
                //删除当前缓存数据
                redisService.deleteString(Thread.currentThread().getName());
            }

        }

  不知道还有没有其他的关联办法,楼主目前还没有想到...

  权当技术积累先记录下来,后续有想法再来这里温习一下

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值