You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure SQL Server单连接并发查询报错:aioodbc遇HY000驱动错误

单连接并发查询Azure SQL Server的问题解答

问题还原

使用aioodbc客户端连接Azure SQL Server时,通过单个连接的cursor并发执行查询,抛出错误:

'HY000', 'The driver did not supply an error!'

但将查询改为逐个串行执行时运行正常,并发执行的示例代码如下:

output1, output2 = await asyncio.gather(
                        execute_fn1(cur, sql1),
                        execute_fn2(cur, sql2)
                    )

核心结论

ODBC不支持通过单个连接并行执行查询。

ODBC连接及其对应的cursor是协程/线程不安全的,同一时间只能处理一个数据库请求。当用asyncio.gather同时调用同一个cursor执行多个查询时,会打乱连接内部的状态管理逻辑,导致驱动抛出无明确信息的错误。

解决方案

1. 为每个并发任务创建独立连接

这是最推荐的方案,每个并发任务使用自己的数据库连接和cursor,避免资源竞争:

async def get_db_connection():
    # 替换为你的数据库连接参数
    conn = await aioodbc.connect(
        dsn="your_dsn",
        user="username",
        password="password",
        database="db_name"
    )
    return conn

async def execute_fn1(sql):
    async with await get_db_connection() as conn:
        async with conn.cursor() as cur:
            await cur.execute(sql)
            result = await cur.fetchall()
            return result

async def execute_fn2(sql):
    async with await get_db_connection() as conn:
        async with conn.cursor() as cur:
            await cur.execute(sql)
            result = await cur.fetchall()
            return result

# 并发执行
output1, output2 = await asyncio.gather(
    execute_fn1(sql1),
    execute_fn2(sql2)
)

2. 对单连接加锁(不推荐)

如果必须复用单个连接,可以通过加锁强制同一时间只有一个任务使用cursor,但这样会让查询变回串行执行,失去并发的意义:

import asyncio

# 全局锁
lock = asyncio.Lock()

async def execute_fn1(cur, sql):
    async with lock:
        await cur.execute(sql)
        result = await cur.fetchall()
        return result

async def execute_fn2(cur, sql):
    async with lock:
        await cur.execute(sql)
        result = await cur.fetchall()
        return result

内容的提问来源于stack exchange,提问作者Shankar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 06:12:14