Become a sponsor

项目采用 AOP(面向切面编程)风格的事务管理机制,通过中间件自动管理数据库事务,业务代码无需手动调用 commit 或 rollback。
传统的事务管理方式需要在业务代码中显式调用 commit 和 rollback,这种方式存在以下问题:
rollback 可能导致数据不一致AOP 事务管理通过中间件自动处理事务,业务代码只需关注业务逻辑。
事务管理通过 src/middleware/transaction.py 实现:
from flask import request, g
from src.core.database import db
def register_transaction(app):
"""注册 AOP 事务管理中间件"""
@app.before_request
def _transaction_begin():
"""请求开始前:标记事务活跃"""
g.transaction_active = True
@app.after_request
def _transaction_commit(response):
"""请求结束后:根据响应状态决定提交或回滚"""
if request.method in ('POST', 'PUT', 'DELETE', 'PATCH'):
if response.status_code == 200:
try:
body = response.get_json()
if body and body.get('code') == 0:
# 业务成功:提交事务
db.session.commit()
else:
# 业务失败:回滚事务
db.session.rollback()
except Exception:
db.session.rollback()
else:
# HTTP 非 200:回滚事务
db.session.rollback()
return response
@app.teardown_request
def _transaction_rollback(exception):
"""请求异常时:回滚事务"""
if exception:
db.session.rollback()
# 移除会话
db.session.remove()| HTTP 方法 | 响应状态 | 业务 code | 事务操作 |
|---|---|---|---|
| POST | 200 | 0(成功) | commit |
| POST | 200 | 1(失败) | rollback |
| PUT | 200 | 0(成功) | commit |
| PUT | 200 | 1(失败) | rollback |
| DELETE | 200 | 0(成功) | commit |
| DELETE | 200 | 1(失败) | rollback |
| PATCH | 200 | 0(成功) | commit |
| PATCH | 200 | 1(失败) | rollback |
| GET | 任意 | 任意 | 不处理(只读) |
| 任意 | 非 200 | 任意 | rollback |
| 任意 | 异常 | 任意 | rollback |
from src.modules.system.position.models import Position
def add_position(data):
"""新增岗位"""
# 创建模型实例
position = Position()
position.name = data['name']
position.status = data['status']
position.sort = data['sort']
# 保存到数据库(仅 flush,不 commit)
position.save()
# 返回成功响应
return R.ok(msg="新增成功")def delete_positions(id_list):
"""批量删除岗位"""
# 批量软删除(仅 flush,不 commit)
PositionRepository.batch_delete(id_list)
# 返回成功响应
return R.ok(msg="删除成功")def transfer_user(user_id, new_dept_id):
"""转移用户部门"""
# 更新用户部门
user = UserRepository.get_by_id(user_id)
user.dept_id = new_dept_id
user.save()
# 更新部门人数统计
dept = DeptRepository.get_by_id(new_dept_id)
dept.user_count = DeptRepository.count_users(new_dept_id)
dept.save()
# 两个操作在同一个事务中,要么都成功,要么都回滚
return R.ok(msg="转移成功")BaseDB 基类提供的 save() 方法只执行 flush,不执行 commit:
class BaseDB:
def save(self):
"""保存模型到数据库(仅 flush,不 commit)"""
db.session.add(self)
db.session.flush()
return selfflush 的作用:
某些特殊场景需要立即提交事务,可以使用 TransactionContext 上下文管理器:
from src.middleware.transaction import TransactionContext
def import_data(file):
"""导入数据(需要立即提交)"""
with TransactionContext():
# 在此上下文中的操作会立即提交
for row in parse_excel(file):
position = Position(**row)
position.save()
# 上下文结束后自动提交
return R.ok(msg="导入成功")某些业务场景需要手动回滚:
from src.core.database import db
def complex_operation():
"""复杂操作(需要手动回滚)"""
try:
# 执行一系列操作
user = User(...)
user.save()
# 检查业务条件
if not check_condition(user):
# 手动回滚
db.session.rollback()
return R.failed("条件不满足")
# 继续其他操作
# ...
return R.ok(msg="操作成功")
except Exception as e:
# 异常时手动回滚
db.session.rollback()
raise重要提示
db.session.commit():事务由中间件统一管理,手动 commit 可能导致事务提前提交db.session.rollback():除非在 try-except 块中需要手动回滚code 字段判断是否需要提交AOP 事务管理通过中间件自动处理数据库事务,业务代码无需手动调用 commit 或 rollback。save() 方法只执行 flush,事务由中间件在请求结束时统一提交或回滚。这种设计简化了业务代码,提高了代码可维护性,同时保证了数据一致性。