交互式事务
警告
事务尚未针对 CockroachDB 进行全面测试。
Prisma Client Python 支持交互式事务,这是一种通用的解决方案,允许您将多个操作作为单个原子操作运行 - 如果任何操作失败,或在事务期间引发任何其他错误,Prisma 将回滚整个事务。
这与 批量查询 不同,因为您可以执行依赖于先前操作结果的操作。
用法
可以使用 Prisma.tx()
方法创建事务,该方法返回一个上下文管理器,当进入时返回一个单独的 Prisma
实例,该实例将所有查询包装在事务中。
from prisma import Prisma
prisma = Prisma()
await prisma.connect()
async with prisma.tx() as transaction:
user = await transaction.user.update(
where={'id': from_user_id},
data={'balance': {'decrement': 50}}
)
if user.balance < 0:
raise ValueError(f'{user.name} does not have enough balance')
await transaction.user.update(
where={'id': to_user_id},
data={'balance': {'increment': 50}}
)
from prisma import Prisma
prisma = Prisma()
prisma.connect()
with prisma.tx() as transaction:
user = transaction.user.update(
where={'id': from_user_id},
data={'balance': {'decrement': 50}}
)
if user.balance < 0:
raise ValueError(f'{user.name} does not have enough balance')
transaction.user.update(
where={'id': to_user_id},
data={'balance': {'increment': 50}}
)
在此示例中,如果引发了 ValueError
,则整个事务将回滚。这意味着第一个 update
调用将被逆转。
如果此示例成功运行,则当上下文管理器退出时,两个数据库写入都将提交,这意味着在应用程序中其他地方运行的查询将访问更新后的数据。
与模型查询一起使用
from prisma import Prisma
from prisma.models import User
prisma = Prisma(auto_register=True)
await prisma.connect()
async with prisma.tx() as transaction:
user = await User.prisma(transaction).update(
where={'id': from_user_id},
data={'balance': {'decrement': 50}}
)
if user.balance < 0:
raise ValueError(f'{user.name} does not have enough balance')
user = await User.prisma(transaction).update(
where={'id': to_user_id},
data={'balance': {'increment': 50}}
)
prisma = Prisma()
prisma.connect()
with prisma.tx() as transaction:
user = User.prisma(transaction).update(
where={'id': from_user_id},
data={'balance': {'decrement': 50}}
)
if user.balance < 0:
raise ValueError(f'{user.name} does not have enough balance')
user = User.prisma(transaction).update(
where={'id': to_user_id},
data={'balance': {'increment': 50}}
)
超时
您可以传递以下选项来配置如何将超时应用于您的事务
max_wait
- Prisma 从数据库获取事务的最大等待时间。默认值为 2 秒
。
timeout
- 事务在被取消和回滚之前可以运行的最大时间。默认值为 5 秒
。
from datetime import timedelta
prisma.tx(
max_wait=timedelta(seconds=2),
timeout=timedelta(seconds=10),
)