解决异步任务中访问ThreadLocal报错的方案及实现

文章讨论了在异步任务中由于ThreadLocal的线程限制导致无法访问用户信息的问题,提出了三种解决方案:转发用户信息、使用InheritableThreadLocal和采用单线程线程池。推荐的方法是通过参数传递用户信息,确保异步任务能正确获取所需数据。同时,提到了每种方案的优缺点和适用场景。
摘要由CSDN通过智能技术生成

在这里插入图片描述

当开发软件程序时,我们通常需要异步记录操作日志和用户信息。操作日志可以用于跟踪系统的运行情况、查询问题以及审计目标的,而使用用户信息记录则可以用于个人化服务、权限管理和统计分析等等方面。然而,在某种情况下,我们可能会遇到以下问题:在异常任务中访问ThreadLocal的信息时报错。

问题现象和产生的原因

异步任务在不同的线路中执行,而ThreadLocal只在当前线路中可见。这意味着,当我们在异步任务中尝试访问之前在主线路或其它线路中设置的ThreadLocal变化量时,就会发生错误。这种错误可能会导致无法正确获取用户信息,并影响到日志记录的准确性和完整性。

解决方案一:转发用户信息(推荐)

为了解决异常步骤中无法访问ThreadLocal的问题,一种常见的解决方法是通过参数传递用户信息。具体而言,我们可以在登录验证通过滤器中,登录成功后将使用用户信息作为参数传递给异常步骤。这样,异步任务就可以直接使用传递的用户信息,而不依赖于ThreadLocal

在现实过程中,我们需要在登录验证过滤器中获取用户信息,并将其传递给异常任务。可以通过在异常任务的结构制造数中接收用户信息参数的方式来现实。这样,在异步任务中就可以使用该用户信息,进行日志记录或其他相关操作。

解决方案二:使用InheritableThreadLocal

另一种解决方案是使用InheritableThreadLocalInheritableThreadLocal代替ThreadLocal,它是ThreadLocal的一个子类,它可以在子线中继承父线中设置的信息。通过使用InheritableThreadLocal我们可以在主线中设置用户消息到ThreadLocal,然后在异常任务的子线程序中获得这些信息。

需要注意的是,使用InheritableThreadLocal可能会引入一些性能开发,并且需要小心处理线路之间的共享数据。在使用时,我们需要确保合适时机设置和清理中的价值,以防止内存泄漏或数据混乱InheritableThreadLocal等问题。

解决方案三:使用单线程的线程池

如果你希望登录过滤器和异步任务在同一个线程中执行,可以使用单线程的线程池来执行异步任务。这样,所有的异步任务都会在同一条线路中按顺序执行,保证登录通过滤器和异步任务的执行在同一条线路上。

在这种方案中,我们需要创建一个单线程的线程池,然后将异常步骤提交给该线程池执行。这样,所有的异常步骤事务都会在同一条线路中执行,可以确保登录过过滤器中设置的ThreadLocal中用户信息在异常操作执行期间可用。

需要注意的是,使用单线程的线程池可能会影响系统的并发性能,因为所有的异常步骤都在同一个线程中顺序执行。因此,该方案适合用于对并发性能要求不高的场景。

方案一详细实现步骤

这里用一个简单的demo项目演示方案一的详细解决步骤

模拟记录操作日志,在查询方法加上Log自定义注解,前端发起请求执行该方法就会执行记录操作日志。

在这里插入图片描述

1、过滤器对请求进行过滤和放行,判断session中是否有用户信息。

在这里插入图片描述
2、如果session中有用户信息则查询数据库校验用户信息,校验通过后返回用户信息。

在这里插入图片描述
3、将用户信息存入session中,下一次请求就会携带用户信息。

在这里插入图片描述
4、将用户信息存入ThreadLocal中并放行。

在这里插入图片描述
5、进入AOP方法增强代码,处理日志信息,这里可以获取到ThreadLocal信息。

在这里插入图片描述
6、处理日志信息方法也可以获取ThreadLocal信息,通过参数传递的方式将用户信息传递给异步任务方法。

在这里插入图片描述
7、进入异步任务方法,这里可以看到通过方法传参可以获取到用户信息,而使用ThreadLocal则获取不到用户信息。

在这里插入图片描述
8、执行SQL将操作日志信息写入到数据库中。

在这里插入图片描述

以上是针对该问题的几种解决方案。具体选择哪种解决方案需要根据具体的业务和需求进行相应的调整。
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

霁晨晨晨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值