# Injected WorkflowContext vs ThreadLocal

**URL:** <https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549>\
**Category:** Community Support\
**Created:** [August 28, 2020, 1:48pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549 "2020-08-28T13:48:53Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![jvassev](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/jvassev/32/248_2.png) [@jvassev](https://community.temporal.io/u/jvassev)\
**Post date:** [August 28, 2020, 1:48pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/1 "2020-08-28T13:48:53Z")

</div>

Hi,  
I was wondering about the design decision to go with a thread-local based Workflow in the Java SDK. Since the lifecycle of the workflow handler instance is controlled by temporal, wouldn’t this design be more natural to Java developers:

```
@WorkflowInterface
public class MyWorkflow {
    @Context
    Logger logger;

    @Context
    Workflow ctx;

    @WorkflowMethod
    public void main() {
       // not using static method anymore
        ctx.sleep(100);
    }
}

```

The @Context annotation would be reusable in actions and can do the proper thing based on the field type - for example replace ThreadLocals with WorkflowThreadLocal, populate loggers with Workflow.getLogger(), etc.

I am assuming that a workload class instance will be serving just one execution - unlike a servlet. I’m new to Temporal so probably I’m missing something 🙂

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [August 28, 2020, 2:18pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/2 "2020-08-28T14:18:19Z")

</div>

The core design that uses thread locals allows to implement workflows without relying on a IoC container.

I agree that a lot of Java developers are using one of such containers and are used to dependency injection. We do plan provide integrations with such containers in the future and the code similar to your sample will be possible.

I believe Spring Boot is the most requested integration.

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [March 29, 2024, 8:34am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/3 "2024-03-29T08:34:56Z")

</div>

Do we have this feature now? I came here looking for a way to pass a Spring container managed Bean into Temporal workflow. Is there any way?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [March 29, 2024, 4:47pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/4 "2024-03-29T16:47:30Z")

</div>

Yes, Temporal provides [Spring Boot](https://github.com/temporalio/sdk-java/tree/master/temporal-spring-boot-autoconfigure-alpha) integration. But it doesn’t support injection into workflow code. This is done on purpose as injecting external objects into the workflow can lead to determinism errors.

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [March 30, 2024, 2:56am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/5 "2024-03-30T02:56:13Z")

</div>

I want to create a database object lock before I start any of the workflows and release that lock after all the workflows are over. How can I achieve that without being able to inject an object of lockRegistry inside the workflow?

Because all the workflows are independently running and only the the parent workflow has end to end child workflows defined.

Does temporal provide anyway to acquire and release db locks?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [March 30, 2024, 3:01am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/6 "2024-03-30T03:01:27Z")

</div>

Temporal workflows cannot perform any IO directly to support deterministic execution.

They have to perform all IO through activities. To acquire and release DB locks, implement correspondent activities, and invoke them from the workflow code. Temporal supports injecting dependencies into activities.

What is your business use case? Why do you need to talk to a DB and especially keep long locks?

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [March 30, 2024, 5:03am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/7 "2024-03-30T05:03:58Z")

</div>

I see. We need to run a long execution and make sure the locks are in place to avoid someone else triggering the same execution.

Also I cannot use the activities to execute this IO because Activities and Workflows are 2 different microservices. The moment I use activities, I have to serialize and deserialize the Lock object to share between the microservices which doesn’t work.

Do you recommend keeping Workflows and Activities in the same microservice? I don’t know why it was designed like this.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [March 30, 2024, 5:31pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/8 "2024-03-30T17:31:52Z")

</div>

You don’t need to use an external DB to ensure the uniqueness of Temporal workflows. They are guaranteed to be unique per WorkflowID out of the box.

Temporal supports routing activities to specific processes and hosts. So, it supports use cases that require some activities to be executed on the same host. This is not needed for your use case, but for cases like media processing, it is necessary.

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [March 31, 2024, 3:29am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/9 "2024-03-31T03:29:33Z")

</div>

There is one legacy app that runs the same code (Workflows) sequentially (not using temporal but plain spring framework) and what I am working on is the new revised app. I want to acquire a lock to provide mutual exclusion between both the apps. This is business requirement to be honest. Seems like I am stuck with the bad design.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [March 31, 2024, 7:06pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/10 "2024-03-31T19:06:40Z")

</div>

Is it possible to communicate with Temporal from the old app? Then, you can use Temporal workflow as a lock. Or locking through DB is the only option that the old app supports?

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [April 1, 2024, 2:17am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/11 "2024-04-01T02:17:38Z")

</div>

The old application is agnostic to the new app and Temporal framework/workflows. So database is the only way to maintain the locks. In the old app the spring’s `JdbcLockregistry` was used considering mutual exclusion at DB layer. Can `ContextPropogater` help me here? I would acquire the lock and store the `Lock` object inside this if it work. Unless we have to serialize and deserialize objects.

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [April 1, 2024, 4:57am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/12 "2024-04-01T04:57:49Z")

</div>

Alternatively, is it possible to acquire a lock and release it before I start my workflow sessions? Right now this is how we start the main session,

```auto

 WorkflowClient.start(myTaskSessionWorkflow::executeMyTaskSession,
                        myTaskSessionWorkflowInitRequest);

```

However, the thread comes out after starting the execution. This is likely not possible given how Temporal works but is it possible to remain in this thread until the `executeMyTaskSession` is completed? May be with some other manner in which I can start workflow sessions?  
Something like the below?

```auto
Lock lock = null;
try {
//acquire lock
 WorkflowClient.start(myTaskSessionWorkflow::executeMyTaskSession,
                        myTaskSessionWorkflowInitRequest);
} finally {
lock.unlock();
}

```

ETA: Looks like java does not have `ContextPropogater` only go and typescript SDKs have it [Search the documentation | Temporal Documentation](https://docs.temporal.io/search?q=ContextPropogater)

ETA 2 - It works with the below code. So I have to manage my logic of locking and unlocking outside the workflows.

```auto
 var lock = lockRegistry.obtain(lockKey);
                try {
                    lock.lock();
                    // start sync and wait for results (or failure)
                    String result = myTaskSessionWorkflow.executeMyTaskSession(myTaskSessionWorkflowInitRequest);
                    LOGGER.info("Result {}", result);
                } finally {
                    lock.unlock();
                }

```

Thank you so much **Maxim** for answering my queries over here. 🙂

Ref: [Foundations - Java SDK feature guide | Temporal Documentation](https://docs.temporal.io/dev-guide/java/foundations#get-workflow-results)

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [April 1, 2024, 7:17pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/13 "2024-04-01T19:17:40Z")

</div>

What does happen currently when the process that took the lock crashes?

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [April 2, 2024, 4:38am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/14 "2024-04-02T04:38:34Z")

</div>

That’s a great question. In that case the lock will auto release in 1 hour. This is more like a lease agreement than locking agreement with spring integration library. There is a TTL set for each lock.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [April 2, 2024, 5:06pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/15 "2024-04-02T17:06:51Z")

</div>

So, is there no way to release this lock by running a separate command/process?

---

<div class="post-metadata">

**Author:** ![Dishi\_Jain](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/dishi_jain/32/5140_2.png) [@Dishi\_Jain](https://community.temporal.io/u/Dishi_Jain)\
**Post date:** [April 3, 2024, 1:11am UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/16 "2024-04-03T01:11:29Z")

</div>

Unfortunately, no. Locks need to be released in the same thread they were starting from. I can technically release them by directly hitting the DB and deleting them but that’s a poor design and other business use cases may get impacted.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [April 3, 2024, 3:28pm UTC](https://community.temporal.io/t/injected-workflowcontext-vs-threadlocal/549/17 "2024-04-03T15:28:33Z")

</div>

I see. Then, I would implement an activity that takes the lock and releases it when canceled. This activity heartbeats while keeping the lock to notify Temporal that it is still alive. When the activity fails to heartbeat the workflow will get an exception and perform whatever cleanup logic possible.
