title: 深入解析事务基础与原子操作原理
date: 2025/04/23 12:07:08
updated: 2025/04/23 12:07:08
author: cmdragon
excerpt:
事务是数据库操作的核心,需满足ACID特性:原子性、一致性、隔离性和持久性。事务隔离级别包括读未提交、读已提交、可重复读和串行化,适用于不同场景。嵌套事务通过上下文管理实现,支持回滚点以部分回滚。实战案例展示了订单系统中的事务处理,包括余额检查和支付失败回滚。常见错误如TransactionManagementError和死锁,需通过正确使用事务装饰器和重试机制解决。课后Quiz探讨了事务隔离和嵌套事务回滚的处理方法。运行环境配置包括依赖安装和FastAPI启动设置。
categories:
tags:
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
在数据库操作中,事务需要满足ACID特性:
# 示例:银行转账的原子操作
from fastapi import APIRouter, Depends
from tortoise.transactions import atomic
router = APIRouter()
@router.post("/transfer")
@atomic() # 使用装饰器包裹事务范围
async def transfer_money(
from_account: str,
to_account: str,
amount: float
):
# 扣减转出账户
from_acc = await Account.get(number=from_account)
from_acc.balance -= amount
await from_acc.save()
# 增加转入账户
to_acc = await Account.get(number=to_account)
to_acc.balance += amount
await to_acc.save()
return {"message": "转账成功"}
级别 | 脏读 | 不可重复读 | 幻读 | 适用场景 |
---|---|---|---|---|
读未提交 | 可能 | 可能 | 可能 | 低并发场景 |
读已提交 | 禁止 | 可能 | 可能 | 默认级别 |
可重复读 | 禁止 | 禁止 | 可能 | 金融系统 |
串行化 | 禁止 | 禁止 | 禁止 | 高精度要求 |
from tortoise.transactions import in_transaction
async def complex_operation():
async with in_transaction() as conn1: # 外层事务
await Model1.create(...)
try:
async with in_transaction(connection=conn1) as conn2: # 内层事务
await Model2.create(...)
await conn2.rollback() # 仅回滚内层操作
except Exception:
pass
await Model3.create(...) # 外层事务继续执行
async def savepoint_demo():
async with in_transaction() as conn:
savepoint = await conn.savepoint() # 创建回滚点
try:
await Model.create(...)
if error_condition:
await savepoint.rollback() # 回滚到保存点
except Exception:
await savepoint.rollback()
from fastapi import Depends
from tortoise.contrib.fastapi import register_tortoise
from tortoise.models import Model
from tortoise import fields
# 数据模型定义
class User(Model):
id = fields.IntField(pk=True)
balance = fields.DecimalField(max_digits=10, decimal_places=2)
class Order(Model):
id = fields.UUIDField(pk=True)
user = fields.ForeignKeyField('models.User')
amount = fields.DecimalField(max_digits=10, decimal_places=2)
status = fields.CharField(max_length=20)
# 事务处理服务
class OrderService:
@staticmethod
@atomic()
async def create_order(user_id: int, amount: float):
user = await User.get(id=user_id)
# 检查余额
if user.balance
错误现象:
TransactionManagementError: Transaction not found for current context
解决方法:
错误日志:
Deadlock found when trying to get lock
处理方案:
from tortoise.exceptions import OperationalError
from fastapi import HTTPException
async def safe_transaction():
try:
async with in_transaction():
# 数据库操作
except OperationalError as e:
if "Deadlock" in str(e):
await asyncio.sleep(0.1) # 随机延迟后重试
return await safe_transaction()
else:
raise HTTPException(status_code=500, detail="数据库错误")
问题:在可重复读隔离级别下,如何处理余额校验时的并发修改?
答案解析:
使用SELECT FOR UPDATE锁定记录:
async def update_balance(user_id: int):
async with in_transaction():
user = await User.select_for_update().get(id=user_id)
# 后续操作
问题:当外层事务捕获内层事务的异常时,如何保证部分提交?
正确答案:
使用保存点机制:
async def nested_transaction():
async with in_transaction() as conn:
savepoint = await conn.savepoint()
try:
# 内层操作
except Exception:
await savepoint.rollback()
# 外层继续执行
安装依赖:
pip install fastapi tortoise-orm uvicorn pydantic
启动配置:
# main.py
from fastapi import FastAPI
app = FastAPI()
register_tortoise(
app,
db_url='sqlite://db.sqlite3',
modules={'models': ['models']},
generate_schemas=True,
add_exception_handlers=True
)
启动命令:
uvicorn main:app --reload
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
,阅读完整的文章:深入解析事务基础与原子操作原理 | cmdragon's Blog
参与评论
手机查看
返回顶部