在关于 Context Vars 的 Python 文档中,描述了一个 Context::run 方法以启用在上下文中执行可调用对象,因此可调用对象对上下文执行的更改包含在复制的上下文中。如果你需要执行一个协程怎么办?为了实现相同的行为,您应该做什么?
就我而言,我想要的是这样的东西来处理可能嵌套事务的事务上下文:
my_ctxvar = ContextVar("my_ctxvar")
async def coro(func, transaction):
token = my_ctxvar.set(transaction)
r = await func()
my_ctxvar.reset(token) # no real need for this, but why not either
return r
async def foo():
ctx = copy_context()
# simplification to one case here: let's use the current transaction if there is one
if tx_owner := my_ctxvar not in ctx:
tx = await create_transaction()
else:
tx = my_ctxvar.get()
try:
r = await ctx.run(coro) # not actually possible
if tx_owner:
await tx.commit()
except Exception as e:
if tx_owner:
await tx.rollback()
raise from e
return r