Skip to content

Commit 3cd02a0

Browse files
committed
Optimize transaction related documents
1 parent aa72def commit 3cd02a0

File tree

1 file changed

+101
-29
lines changed

1 file changed

+101
-29
lines changed

docs/advanced/transaction.md

Lines changed: 101 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SQLAlchemy CRUD Plus 基于 SQLAlchemy 2.0 的现代事务管理模式,提供
1010
# 推荐的事务模式
1111
async with async_db_session.begin() as session:
1212
# 在这个块中的所有操作都在同一个事务中
13-
user_data = {"name": "张三", "email": "zhangsan@example.com"}
13+
user_data = UserCreate(name="张三", email="zhangsan@example.com")
1414
user = await user_crud.create_model(session, user_data)
1515

1616
# 如果没有异常,事务会自动提交
@@ -25,7 +25,7 @@ async with async_db_session() as session:
2525
# 开始事务
2626
await session.begin()
2727

28-
user_data = {"name": "李四", "email": "lisi@example.com"}
28+
user_data = UserCreate(name="李四", email="lisi@example.com")
2929
user = await user_crud.create_model(session, user_data)
3030

3131
# 手动提交
@@ -37,17 +37,27 @@ async with async_db_session() as session:
3737
raise e
3838
```
3939

40-
### 使用 commit 参数
40+
### 使用 flush 和 commit 参数
41+
42+
**flush**:将更改刷新到数据库但不提交事务,用于获取自动生成的主键或在同一事务中使用新创建的记录。
43+
44+
**commit**:立即提交事务,适用于独立的单个操作。
4145

4246
```python
47+
# 使用 flush 获取自动生成的主键
48+
user_data = UserCreate(name="张三", email="zhangsan@example.com")
49+
user = await user_crud.create_model(session, user_data, flush=True)
50+
# 此时 user.id 已可用,但事务未提交
51+
4352
# 自动提交单个操作
53+
user_data = UserCreate(name="李四", email="lisi@example.com")
4454
user = await user_crud.create_model(session, user_data, commit=True)
4555

4656
# 自动提交更新操作
47-
await user_crud.update_model(session, user_id, update_data, commit=True)
57+
await user_crud.update_model(session, pk=user_id, obj=update_data, commit=True)
4858

4959
# 自动提交删除操作
50-
await user_crud.delete_model(session, user_id, commit=True)
60+
await user_crud.delete_model(session, pk=user_id, commit=True)
5161
```
5262

5363
## 复杂事务场景
@@ -56,20 +66,20 @@ await user_crud.delete_model(session, user_id, commit=True)
5666

5767
```python
5868
async with async_db_session.begin() as session:
59-
# 创建用户
60-
user_data = {"name": "王五", "email": "wangwu@example.com"}
69+
# 创建用户(使用 flush 获取主键)
70+
user_data = UserCreate(name="王五", email="wangwu@example.com")
6171
user = await user_crud.create_model(session, user_data, flush=True)
6272

63-
# 创建个人资料
64-
profile_data = {"user_id": user.id, "bio": "个人简介"}
73+
# 创建个人资料(使用获取到的用户主键)
74+
profile_data = ProfileCreate(user_id=user.id, bio="个人简介")
6575
profile = await profile_crud.create_model(session, profile_data)
6676

6777
# 创建文章
68-
post_data = {
69-
"title": "我的第一篇文章",
70-
"content": "文章内容...",
71-
"author_id": user.id
72-
}
78+
post_data = PostCreate(
79+
title="我的第一篇文章",
80+
content="文章内容...",
81+
author_id=user.id
82+
)
7383
post = await post_crud.create_model(session, post_data)
7484

7585
# 所有操作要么全部成功,要么全部回滚
@@ -86,16 +96,17 @@ async with async_db_session.begin() as session:
8696

8797
if existing_user:
8898
# 更新现有用户
89-
user_update = {"last_login": datetime.now()}
90-
user = await user_crud.update_model(
91-
session, existing_user.id, user_update
99+
user_update = UserUpdate(last_login=datetime.now())
100+
await user_crud.update_model(
101+
session, pk=existing_user.id, obj=user_update
92102
)
103+
user = existing_user
93104
else:
94105
# 创建新用户
95-
user_data = {
96-
"name": "新用户",
97-
"email": "test@example.com"
98-
}
106+
user_data = UserCreate(
107+
name="新用户",
108+
email="test@example.com"
109+
)
99110
user = await user_crud.create_model(session, user_data)
100111

101112
return user
@@ -107,15 +118,15 @@ async with async_db_session.begin() as session:
107118
async with async_db_session.begin() as session:
108119
# 批量创建用户
109120
users_data = [
110-
{"name": f"用户{i}", "email": f"user{i}@example.com"}
121+
UserCreate(name=f"用户{i}", email=f"user{i}@example.com")
111122
for i in range(100)
112123
]
113124
users = await user_crud.create_models(session, users_data)
114125

115126
# 批量更新
116127
for user in users:
117128
await user_crud.update_model(
118-
session, user.id, {"is_active": True}
129+
session, pk=user.id, obj={"is_active": True}
119130
)
120131
```
121132

@@ -126,15 +137,15 @@ async with async_db_session.begin() as session:
126137
```python
127138
async with async_db_session.begin() as session:
128139
# 主事务
129-
user_data = {"name": "主用户", "email": "main@example.com"}
140+
user_data = UserCreate(name="主用户", email="main@example.com")
130141
user = await user_crud.create_model(session, user_data, flush=True)
131142

132143
# 创建保存点
133144
savepoint = await session.begin_nested()
134145

135146
try:
136147
# 嵌套事务
137-
profile_data = {"user_id": user.id, "bio": "可能失败的操作"}
148+
profile_data = ProfileCreate(user_id=user.id, bio="可能失败的操作")
138149
profile = await profile_crud.create_model(session, profile_data)
139150

140151
# 提交保存点
@@ -186,32 +197,93 @@ async def concurrent_transactions():
186197
# 并发处理
187198
tasks = []
188199
for i in range(10):
189-
user_data = {"name": f"用户{i}", "email": f"user{i}@example.com"}
200+
user_data = UserCreate(name=f"用户{i}", email=f"user{i}@example.com")
190201
task = process_user(user_data)
191202
tasks.append(task)
192203

193204
results = await asyncio.gather(*tasks, return_exceptions=True)
194205
return results
195206
```
196207

208+
## flush 和 commit 参数详解
209+
210+
### flush 参数
211+
212+
`flush=True` 将更改发送到数据库但不提交事务:
213+
214+
```python
215+
async with async_db_session.begin() as session:
216+
# 创建用户并立即获取主键
217+
user_data = UserCreate(name="张三", email="zhangsan@example.com")
218+
user = await user_crud.create_model(session, user_data, flush=True)
219+
220+
# 此时 user.id 已可用,可用于关联操作
221+
profile_data = ProfileCreate(user_id=user.id, bio="用户简介")
222+
profile = await profile_crud.create_model(session, profile_data)
223+
224+
# 事务在 with 块结束时自动提交
225+
```
226+
227+
**使用场景:**
228+
229+
- 需要获取自动生成的主键
230+
- 在同一事务中创建关联记录
231+
- 确保数据一致性检查
232+
233+
### commit 参数
234+
235+
`commit=True` 立即提交事务:
236+
237+
```python
238+
# 独立操作,立即提交
239+
user_data = UserCreate(name="李四", email="lisi@example.com")
240+
user = await user_crud.create_model(session, user_data, commit=True)
241+
242+
# 适用于单个操作
243+
await user_crud.update_model(session, pk=1, obj={"name": "新名称"}, commit=True)
244+
await user_crud.delete_model(session, pk=1, commit=True)
245+
```
246+
247+
**使用场景:**
248+
249+
- 独立的单个操作
250+
- 不需要与其他操作组合
251+
- 简化代码结构
252+
253+
### 参数组合使用
254+
255+
```python
256+
# ❌ 错误:不要同时使用 flush 和 commit
257+
user = await user_crud.create_model(session, user_data, flush=True, commit=True)
258+
259+
# ✅ 正确:根据需要选择其一
260+
user = await user_crud.create_model(session, user_data, flush=True) # 获取主键
261+
user = await user_crud.create_model(session, user_data, commit=True) # 立即提交
262+
```
263+
197264
## 最佳实践
198265

199266
1. **优先使用自动事务管理**
200267
- 使用 `async with session.begin()` 模式
201268
- 让异常自然传播以触发回滚
202269
- 避免手动管理事务状态
203270

204-
2. **合理控制事务范围**
271+
2. **合理使用 flush 和 commit**
272+
- 需要主键时使用 `flush=True`
273+
- 独立操作时使用 `commit=True`
274+
- 避免在事务块中使用 `commit=True`
275+
276+
3. **合理控制事务范围**
205277
- 保持事务尽可能短小
206278
- 避免在事务中执行耗时操作
207279
- 考虑使用分批处理
208280

209-
3. **错误处理**
281+
4. **错误处理**
210282
- 在事务外部处理业务逻辑错误
211283
- 使用保存点处理部分失败场景
212284
- 记录事务失败的详细信息
213285

214-
4. **性能优化**
286+
5. **性能优化**
215287
- 合理设置事务隔离级别
216288
- 使用并发处理独立事务
217289
- 避免不必要的事务嵌套

0 commit comments

Comments
 (0)