TransmittableThreadLocal Practice: Solving Multi-Country Business Context Propagation in E-commerce
The article explains how to reliably propagate country‑specific context across request handling, database access, and asynchronous thread pools in multi‑country e‑commerce by replacing simple ThreadLocal and InheritableThreadLocal with Alibaba’s TransmittableThreadLocal, demonstrating its integration with Spring MVC/Boot, MyBatis, Dubbo, and custom executors for both sharded and non‑sharded databases.
This article discusses how to propagate country-specific information (including multi-language, multi-country, multi-timezone, and localization) through the entire request chain in a multi-country e-commerce scenario, starting from India and expanding to other countries.
1. ThreadLocal
ThreadLocal is the simplest solution - after identifying the country at the entry point, store it in ThreadLocal so that subsequent code, Redis, and DB operations can access the country information. Each Thread has its own threadLocals (ThreadLocalMap) containing weak-referenced Entries. The get() method retrieves the current thread's value, while set() modifies the corresponding value in the thread's ThreadLocalMap.
2. InheritableThreadLocal
For asynchronous thread processing scenarios, InheritableThreadLocal can pass ThreadLocal content from parent to child threads. It operates on inheritableThreadLocals instead of threadLocals. When creating a new thread, it checks if the parent's inheritableThreadLocals is null; if not, it copies the data to the child thread. However, InheritableThreadLocal has a critical limitation with thread pools: when a thread is reused, it does not trigger the copy operation from the parent's inheritableThreadLocals, so newly set values in the main thread will not take effect.
3. TransmittableThreadLocal (TTL)
Alibaba's open-source TransmittableThreadLocal solves the thread pool problem. By using TtlExecutors to wrap the thread pool, before each task execution, it copies the current main thread's TransmittableThreadLocal data to the child thread, and clears it after execution. The implementation uses TtlRunnable to capture the ThreadLocalMap via capture(), replay() to restore the child thread's original values and set captured values, and restore() to recover the original values after task completion.
4. Practical Application in Overseas E-commerce
Scenario 1: Non-sharded database with sharded data rows + SpringMVC
For HTTP requests, parse the country code from URL or cookie, store it in TransmittableThreadLocal, read it in MyBatis interceptor to modify SQL with country parameters, and use TtlExecutors to wrap custom thread pools for multi-threaded scenarios.
Scenario 2: Sharded database + SpringBoot
Each country has an independent database. Use @Async annotation with custom thread pool wrapped by TtlThreadPoolExecutors. For Dubbo interfaces and HTTP interfaces that cannot determine country info, add country parameters in input and set country info to TransmittableThreadLocal via interceptor or manually.
vivo Internet Technology
Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.