Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
被阻止的Python异步函数调用也会阻止另一个异步函数_Python_Python 3.x_Python Asyncio_Fastapi - Fatal编程技术网

被阻止的Python异步函数调用也会阻止另一个异步函数

被阻止的Python异步函数调用也会阻止另一个异步函数,python,python-3.x,python-asyncio,fastapi,Python,Python 3.x,Python Asyncio,Fastapi,我使用FastAPI开发访问SQL Server的数据层API。 无论是使用pytds还是pyodbc, 如果有数据库事务导致任何请求挂起, 所有其他请求都将被阻止。(即使没有数据库操作) 复制: 有意执行可序列化的SQL Server会话,开始事务,不回滚或提交 使用异步处理程序函数向API发送请求,如下所示: 并使用异步处理程序函数向同一应用程序的API发送请求,如下所示: 我预计步骤2会挂起,步骤3会在2秒后直接返回。 但是,如果事务没有提交或回滚,则步骤3永远不会返回 如何使这些处理程序

我使用FastAPI开发访问SQL Server的数据层API。 无论是使用pytds还是pyodbc, 如果有数据库事务导致任何请求挂起, 所有其他请求都将被阻止。(即使没有数据库操作)

复制:

  • 有意执行可序列化的SQL Server会话,开始事务,不回滚或提交
  • 使用异步处理程序函数向API发送请求,如下所示:
  • 并使用异步处理程序函数向同一应用程序的API发送请求,如下所示:
  • 我预计步骤2会挂起,步骤3会在2秒后直接返回。 但是,如果事务没有提交或回滚,则步骤3永远不会返回


    如何使这些处理程序函数同时工作?

    原因是
    rs=future.result()
    实际上是一个阻塞调用-请参阅。不幸的是,
    executor.submit()
    没有返回可等待的对象(
    concurrent.futures.Future
    不同于
    asyncio.Future

    您可以使用
    asyncio.wrap_future
    ,它接受
    concurrent.future
    并返回
    asyncio.future
    (请参阅)。新的
    future
    对象是可等待的,因此您可以将阻塞函数转换为异步函数

    一个例子:

    导入异步IO
    进口期货
    async def my_async():
    以concurrent.futures.ThreadPoolExecutor()作为执行器:
    未来=执行者提交(λx:x+1,1)
    return wait asyncio.wrap_future(未来)
    打印(asyncio.run(my_async()))
    

    在您的代码中,只需将
    rs=future.result()
    更改为
    rs=wait asyncio.wrap_future(future)
    并使整个函数
    async
    。这应该会很神奇,祝您好运!:)

    请更好地解释。代码不一致,即调用与函数名不匹配我更新了函数名。问题是,即使FastAPI使用asyncio,我也在线程池中执行包装。步骤2中的处理程序仍然会阻塞步骤3中的处理程序。然而,步骤3从不涉及任何数据库操作…
    async
    用于协作并发。使用阻塞、正则函数是不合作的。因此,简单的答案是“不要使用阻塞函数”。你到底在找什么?这能回答你的问题吗?不它与睡眠无关,我已经使用了asyncio.sleep。问题是数据库锁导致异步函数挂起,另一个异步请求被阻止。。。这不是我所期望的。。。
        INSERT INTO [dbo].[KVStore] VALUES ('1', '1', 0)
        begin tran
        SET TRANSACTION ISOLATION LEVEL Serializable
        SELECT * FROM [dbo].[KVStore]
    
        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()
    
    
    
        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)