【发布时间】:2020-08-19 02:52:10
【问题描述】:
我使用 FastAPI 开发访问 SQL Server 的数据层 API。 无论使用 pytds 还是 pyodbc, 如果有数据库事务导致任何请求挂起, 所有其他请求都将被阻止。 (即使没有数据库操作)
转载:
- 有意执行可序列化的 SQL Server 会话,开始事务并且不回滚或提交
INSERT INTO [dbo].[KVStore] VALUES ('1', '1', 0)
begin tran
SET TRANSACTION ISOLATION LEVEL Serializable
SELECT * FROM [dbo].[KVStore]
- 使用异步处理函数向 API 发送请求,如下所示:
def kv_delete_by_key_2_sql():
conn = pytds.connect(dsn='192.168.0.1', database=cfg.kvStore_db, user=cfg.kvStore_uid,
password=cfg.kvStore_upwd, port=1435, autocommit=True)
engine = conn.cursor()
try:
sql = "delete KVStore; commit"
with concurrent.futures.ThreadPoolExecutor() as executor:
future = executor.submit(engine.execute, sql)
rs = future.result()
j = {
'success': True,
'rowcount': rs.rowcount
}
return jsonable_encoder(j)
except Exception as exn:
j = {
'success': False,
'reason': exn_handle(exn)
}
return jsonable_encoder(j)
@app.post("/kvStore/delete")
async def kv_delete(request: Request, type_: Optional[str] = Query(None, max_length=50)):
request_data = await request.json()
return kv_delete_by_key_2_sql()
- 然后使用异步处理函数向同一应用的 API 发送请求,如下所示:
async def hangit0(request: Request, t: int = Query(0)):
print(t, datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
await asyncio.sleep(t)
print(t, datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
j = {
'success': True
}
return jsonable_encoder(j)
@app.get("/kvStore/hangit/")
async def hangit(request: Request, t: int = Query(0)):
return await hangit0(request, t)
我预计 step.2 会挂起,而 step.3 应该在 2 秒后直接返回。 但是,如果事务未提交或回滚,则 step.3 永远不会返回...
如何使这些处理函数同时工作?
【问题讨论】:
-
请解释清楚。代码不连贯,即调用与函数名不匹配
-
我更新了函数名。问题是即使 FastAPI 使用 asyncio,我也在线程池中包装执行。 step.2 中的处理程序仍然阻塞 step.3 中的处理程序。但是,step.3 从不涉及任何数据库操作...
-
async用于合作并发。使用阻塞的常规函数是不合作的。所以简单的答案是“不要使用阻塞函数”。您到底在寻找什么? -
不...它与睡眠无关,我已经使用asyncio.sleep。问题是数据库锁导致异步函数挂起,又阻塞了另一个异步请求……这不是我的预期……
标签: python python-3.x python-asyncio fastapi