处理TCP提供程序:错误代码0x68(104)

2022-04-24 00:00:00 python pyodbc

问题描述

我正在使用此代码将我的数据库与客户端同步:

    import pyodbc

    SYNC_FETCH_ARRAY_SIZE=25000

    # define connection + cursor
    connection = pyodbc.connect()
    cursor = connection.cursor()

    query = 'select some_columns from mytable'
    cursor.execute(query)

    while True:
        rows = cursor.fetchmany(SYNC_FETCH_ARRAY_SIZE) # <<< error here

        if not rows:
            break

        insert_to_our_db(rows)

    cursor.close()

我间歇性地收到以下错误:

File "....py", line 120, in ...
  rows = sg_cur.fetchmany(SYNC_FETCH_ARRAY_SIZE)
pyodbc.OperationalError: ('08S01', '[08S01] [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x68 (104) (SQLGetData)')

我应该如何处理此错误?这是连接上的错误(因此我需要关闭并重新创建连接)还是游标上的错误,我只需要添加重试?

我将添加以下代码来重试(代替抛出错误的行),这足以解决问题吗?如果遇到TCP错误,重试是否会有任何效果?

MAX_RETRIES=5

def get_rows(retry_count=0):
    """
    Wrapper function to add retry functionality to fetchmany
    """
    try:
        rows = sg_cur.fetchmany(SYNC_FETCH_ARRAY_SIZE)

    except Exception as e:
        if retry_count >= MAX_RETRIES:
            raise ConnectionError(f'fetchmany caused the error: {e}')

        else:
            logger.debug(f'Error in get_rows: {e}, attempt: {retry_count}/{MAX_RETRIES}')
            retry_count += 1
            return get_rows(retry_count=retry_count)

    return rows

编辑:

GitHub上存在此问题。在此期间,有什么可行的解决办法?

  • insert_to_our_db之后的最后一次读取存储在我们的数据库中,然后在出现错误时从那里重新启动
  • 只需再次运行整个过程

备注:

  • 错误是间歇性的,因此很难测试
  • 我正在从另一台主机上的客户端数据库同步一个大表。因此,我需要一次更新/插入所有行,以确保数据是最新的
  • 我无法更改客户端的数据库

解决方案

我意识到我要插入的表没有索引。

为了添加行,我运行了upsert,以避免重复。向表添加索引修复了我的问题。

看看其他有此问题的人,这似乎是公认的解决方案。不管怎样,我绝对应该给这张表建立索引--吸取了教训。

编辑。我将不接受此答案,希望有人能就此问题提供更多信息。但对我来说,添加索引(加快了事务处理速度)解决了这个问题。

相关文章