处理TCP提供程序:错误代码0x68(104)
问题描述
我正在使用此代码将我的数据库与客户端同步:
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,以避免重复。向表添加索引修复了我的问题。
看看其他有此问题的人,这似乎是公认的解决方案。不管怎样,我绝对应该给这张表建立索引--吸取了教训。
编辑。我将不接受此答案,希望有人能就此问题提供更多信息。但对我来说,添加索引(加快了事务处理速度)解决了这个问题。
相关文章