# Motive for synchronous connections

**URL:** <https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745>\
**Category:** Async\
**Created:** [July 6, 2024, 12:39pm UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745 "2024-07-06T12:39:15Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bmos](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/bmos/32/22436_2.png) [@bmos](https://forum.djangoproject.com/u/bmos)\
**Post date:** [July 6, 2024, 12:39pm UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745/1 "2024-07-06T12:39:15Z")

</div>

Are there good reasons for Django using synchronous connection and cursors as opposed to async ones? We are thinking of extending Django with support for async connections and are wondering if sync-only is a design decision or just something that hasn’t been implemented yet.

Bonus question:  
Why does Django enforce thread-locality of connections when psycopg connections are thread-safe?

---

<div class="post-metadata">

**Author:** ![nanorepublica](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/nanorepublica/32/14211_2.png) [@nanorepublica](https://forum.djangoproject.com/u/nanorepublica)\
**Post date:** [July 6, 2024, 3:31pm UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745/2 "2024-07-06T15:31:50Z")

</div>

If you haven’t already the [Async DEP](https://github.com/django/deps/blob/main/accepted/0009-async.rst) is probably worth a read as I imagine it will answer most if not all of your questions.

---

<div class="post-metadata">

**Author:** ![bmos](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/bmos/32/22436_2.png) [@bmos](https://forum.djangoproject.com/u/bmos)\
**Post date:** [July 6, 2024, 5:17pm UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745/3 "2024-07-06T17:17:38Z")

</div>

Yes, thank you - that answered a lot. The only question remaining is whether or not it is possible to use atomic transactions for code that is async. Is it safe to enter an atomic block in a sync function and then start an event loop within that block? Will the asynchronous code respect the atomic transaction block? Does it work if one were to use async\_to\_sync?  
I.e. would the following code from this [post](https://stackoverflow.com/questions/74575922/how-to-use-transaction-with-async-functions-in-django) have desirable behaviour?

```auto
from django.db.transaction import Atomic
from asgiref.sync import sync_to_async

class AsyncAtomicContextManager(Atomic):
    def __init__ (self, using=None, savepoint=True, durable=False):
        super(). __init__ (using, savepoint, durable)

    async def __aenter__ (self):
        await sync_to_async(super(). __enter__ )()
        return self

    async def __aexit__ (self, exc_type, exc_value, traceback):
        await sync_to_async(super(). __exit__ )(exc_type, exc_value, traceback)

```

---

<div class="post-metadata">

**Author:** ![nanorepublica](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/nanorepublica/32/14211_2.png) [@nanorepublica](https://forum.djangoproject.com/u/nanorepublica)\
**Post date:** [July 6, 2024, 9:25pm UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745/4 "2024-07-06T21:25:48Z")

</div>

This is where I bow out as I have yet to require async in any of my Django work so far.

I am sure someone more knowledgable with answer!

---

<div class="post-metadata">

**Author:** ![bigfootjon](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/bigfootjon/32/12068_2.png) [@bigfootjon](https://forum.djangoproject.com/u/bigfootjon)\
**Post date:** [July 11, 2024, 2:48am UTC](https://forum.djangoproject.com/t/motive-for-synchronous-connections/32745/5 "2024-07-11T02:48:59Z")

</div>

(I’ve been a bit checked out of this problem space, so things may have changed)

> [@bmos](#):
>
> Is it safe to enter an atomic block in a sync function and then start an event loop within that block?

I think theoretically this could work, but I’m not sure it’s actually supported and not guaranteed to do so. And it might not be safe:

> [@bmos](#):
>
> Will the asynchronous code respect the atomic transaction block?

If the _only_ asynchronous code running in an event loop inside your entire application takes place inside an atomic block then _maybe_ this would work (as listed above). The problem comes in when you have _any other_ async code running at the same time. Let’s say you have the following code:

```auto
asyncio.create_task(complex_job_with_db_usage_that_yields_several_times()) # 1
async with AsyncAtomicContextManager():
    exists = await Model.objects.aget(...) # 2
    if not exists:
        await Model.objects.acreate(...) # 3

```

Task 1 executes first and is scheduled on the event loop. The next time control is yielded back to the event loop it will start to run. Then async task 2 happens, and while the database is processing our query due to the `await` control will be handed back to the asyncio loop to find something else to do. At this point, we’re supposedly inside an atomic context but suddenly task 1 starts running again! Since Django’s internals do not support async atomic block there is nothing stopping task 1 from reading and writing data that conflicts with the actions taken inside the atomic block. Then, by the time task 3 starts running the invariant we’re trying to uphold is no longer valid.

In summary, due to the complexities involved there isn’t a solution to this problem right now.
