0
# Transaction Management
1
2
Database transaction support for ensuring data consistency across multiple operations. Provides both context manager and decorator approaches for transaction handling.
3
4
## Capabilities
5
6
### Transaction Context Manager
7
8
Context manager for running code within a database transaction.
9
10
```python { .api }
11
from tortoise.transactions import in_transaction
12
13
def in_transaction(connection_name=None):
14
"""
15
Transaction context manager.
16
17
Run code inside async with in_transaction() to execute within one transaction.
18
If error occurs, transaction will rollback.
19
20
Args:
21
connection_name (str, optional): Name of connection to use.
22
Required if multiple databases configured.
23
24
Returns:
25
TransactionContext: Context manager for transaction
26
"""
27
```
28
29
### Transaction Decorator
30
31
Decorator for wrapping functions in database transactions.
32
33
```python { .api }
34
from tortoise.transactions import atomic
35
36
def atomic(connection_name=None):
37
"""
38
Transaction decorator.
39
40
Wrap functions with this decorator to run them within one transaction.
41
If function raises exception, transaction will rollback.
42
43
Args:
44
connection_name (str, optional): Name of connection to use.
45
Required if multiple databases configured.
46
47
Returns:
48
Function decorator for transaction handling
49
"""
50
```
51
52
## Usage Examples
53
54
### Context Manager Usage
55
56
```python
57
from tortoise.transactions import in_transaction
58
from myapp.models import User, Profile
59
60
async def create_user_with_profile():
61
async with in_transaction():
62
# All operations within this block run in same transaction
63
user = await User.create(name="Alice", email="alice@example.com")
64
profile = await Profile.create(user=user, bio="Software Engineer")
65
66
# If any operation fails, entire transaction rolls back
67
return user
68
```
69
70
### Decorator Usage
71
72
```python
73
from tortoise.transactions import atomic
74
from myapp.models import User, Order
75
76
@atomic()
77
async def process_order(user_id, items):
78
"""Process order atomically."""
79
user = await User.get(id=user_id)
80
81
# Deduct balance
82
total_cost = sum(item.price for item in items)
83
if user.balance < total_cost:
84
raise ValueError("Insufficient balance")
85
86
user.balance -= total_cost
87
await user.save()
88
89
# Create order
90
order = await Order.create(user=user, total=total_cost)
91
92
# If any step fails, all changes are rolled back
93
return order
94
```
95
96
### Multiple Database Connections
97
98
```python
99
from tortoise.transactions import in_transaction, atomic
100
101
# Specify connection for multiple database setup
102
async def multi_db_operation():
103
async with in_transaction("users_db"):
104
await User.create(name="Alice")
105
106
async with in_transaction("orders_db"):
107
await Order.create(total=100)
108
109
@atomic("analytics_db")
110
async def update_analytics():
111
# Transaction on specific database
112
await AnalyticsRecord.create(event="user_signup")
113
```
114
115
## Transaction Behavior
116
117
### Rollback Conditions
118
119
Transactions automatically rollback when:
120
- Any unhandled exception is raised within the transaction
121
- Database constraint violations occur
122
- Connection errors happen during the transaction
123
124
### Nested Transactions
125
126
Tortoise ORM handles nested transactions using database savepoints:
127
128
```python
129
async with in_transaction():
130
await User.create(name="Alice")
131
132
try:
133
async with in_transaction(): # Nested transaction (savepoint)
134
await User.create(name="Bob")
135
raise Exception("Something went wrong")
136
except:
137
pass # Inner transaction rolled back to savepoint
138
139
# Outer transaction continues
140
await User.create(name="Charlie") # This will still be committed
141
```
142
143
### Connection Management
144
145
- If no `connection_name` specified, uses default connection
146
- With single database, automatically uses that connection
147
- With multiple databases, `connection_name` is required
148
- Raises `ParamsError` if connection specification is ambiguous