@@ -67,6 +67,7 @@ A transaction can be acquired from the database connection pool:
6767async with database.transaction():
6868 ...
6969```
70+
7071It can also be acquired from a specific database connection:
7172
7273``` python
@@ -95,8 +96,54 @@ async def create_users(request):
9596 ...
9697```
9798
98- Transaction blocks are managed as task-local state. Nested transactions
99- are fully supported, and are implemented using database savepoints.
99+ Transaction state is stored in the context of the currently executing asynchronous task.
100+ This state is _ inherited_ by tasks that are started from within an active transaction:
101+
102+ ``` python
103+ async def add_excitement (database : Database, id : int ):
104+ await database.execute(
105+ " UPDATE notes SET text = CONCAT(text, '!!!') WHERE id = :id" ,
106+ {" id" : id }
107+ )
108+
109+
110+ async with Database(database_url) as database:
111+ async with database.transaction():
112+ # This note won't exist until the transaction closes...
113+ await database.execute(
114+ " INSERT INTO notes(id, text) values (1, 'databases is cool')"
115+ )
116+ # ...but child tasks inherit transaction state!
117+ await asyncio.create_task(add_excitement(database, id = 1 ))
118+
119+ await database.fetch_val(" SELECT text FROM notes WHERE id=1" )
120+ # ^ returns: "databases is cool!!!"
121+ ```
122+
123+ !!! note
124+ In python 3.11, you can opt-out of context propagation by providing a new context to
125+ [ ` asyncio.create_task ` ] ( https://docs.python.org/3.11/library/asyncio-task.html#creating-tasks ) .
126+
127+ Nested transactions are fully supported, and are implemented using database savepoints:
128+
129+ ``` python
130+ async with databases.Database(database_url) as db:
131+ async with db.transaction() as outer:
132+ # Do something in the outer transaction
133+ ...
134+
135+ # Suppress to prevent influence on the outer transaction
136+ with contextlib.suppress(ValueError ):
137+ async with db.transaction():
138+ # Do something in the inner transaction
139+ ...
140+
141+ raise ValueError (' Abort the inner transaction' )
142+
143+ # Observe the results of the outer transaction,
144+ # without effects from the inner transaction.
145+ await db.fetch_all(' SELECT * FROM ...' )
146+ ```
100147
101148Transaction isolation-level can be specified if the driver backend supports that:
102149
0 commit comments