如何在不锁定的情况下对具有相关 ID 的单例进行多线程处理 "Cross-tier"?
How to multi-thread "Cross-tier" a singleton with a correlation id without locking?
所以我们使用带有相关 ID 的公共状态上下文单例来进行集中式日志记录。目的是在我们的整个过程中跟踪 id 并关联不同的层。
状态上下文被多个 dll 和多个用户访问。
当多线程发挥作用时,困难就来了:
- 进程 1 已被用户 1 触发
- 关联 ID 设置为 {1}
- DLL A 访问状态上下文并获取关联 ID {1}
- 在进程 1 完成之前,进程 2 已被用户 2 触发
- 关联 ID 设置为 {2}
- 来自第一个进程访问状态上下文的 DLL B,关联 ID 为 {2},而它应该是 {1}
我们如何解决这个问题?
我们不认为锁定是我们的解决方案?还有其他想法吗?
这是一张图
(S)->[ CorrelationID {get;set} ]
^ ^ ^
U1 <--> | | | O
U2 <--> [DLLA] <--> [DLLB] <--> [DLLC] <--> | |
U3 <-->
{Web} <--> {Domain} <-> {Data Access} <--> {DB}
(<-- Process / Thread --> )
{} = 可能的 DLL 示例
每个用户的进程应该有 1 个关联 ID
可能是,ThreadLocal?
https://msdn.microsoft.com/en-us/library/dd642243%28v=vs.100%29.aspx
经过大量研究,我们找到了解决方案。
我们利用.Net Framework
中的LogicalCallContext Class
那么 LogicalCalContext Class 所做的就是利用 .Net Framework,它通过保留回调将键值保留在池中,即使它跳转线程也是如此。
Learn how to Flow Data across threads...
post 中的评论也引用了 Serilog,因此您可能想看一看。
所以我们使用带有相关 ID 的公共状态上下文单例来进行集中式日志记录。目的是在我们的整个过程中跟踪 id 并关联不同的层。
状态上下文被多个 dll 和多个用户访问。
当多线程发挥作用时,困难就来了:
- 进程 1 已被用户 1 触发
- 关联 ID 设置为 {1}
- DLL A 访问状态上下文并获取关联 ID {1}
- 在进程 1 完成之前,进程 2 已被用户 2 触发
- 关联 ID 设置为 {2}
- 来自第一个进程访问状态上下文的 DLL B,关联 ID 为 {2},而它应该是 {1}
我们如何解决这个问题?
我们不认为锁定是我们的解决方案?还有其他想法吗?
这是一张图
(S)->[ CorrelationID {get;set} ]
^ ^ ^
U1 <--> | | | O
U2 <--> [DLLA] <--> [DLLB] <--> [DLLC] <--> | |
U3 <-->
{Web} <--> {Domain} <-> {Data Access} <--> {DB}
(<-- Process / Thread --> )
{} = 可能的 DLL 示例
每个用户的进程应该有 1 个关联 ID
可能是,ThreadLocal
经过大量研究,我们找到了解决方案。
我们利用.Net Framework
中的LogicalCallContext Class那么 LogicalCalContext Class 所做的就是利用 .Net Framework,它通过保留回调将键值保留在池中,即使它跳转线程也是如此。
Learn how to Flow Data across threads...
post 中的评论也引用了 Serilog,因此您可能想看一看。