Oracle表不可访问时如何实现持续尝试写入数据?
实现方案
你可以通过调整异常捕获粒度、增加插入失败重试逻辑实现需求,同时原有脚本的SQL拼接写法存在注入风险,也同步优化为参数化查询,优化后代码如下:
import cx_Oracle import config import time # 单次插入最大重试次数,可根据需求调整,设为0则无限重试 MAX_RETRY_COUNT = 5 # 每次重试间隔秒数 RETRY_INTERVAL = 10 def get_db_connection(): """封装获取数据库连接的公共方法,连接异常时也支持重试""" while True: try: connection = cx_Oracle.connect( config.username, config.password, config.dsn, encoding=config.encoding ) return connection except cx_Oracle.Error as e: print(f"数据库连接失败,错误信息:{e},{RETRY_INTERVAL}秒后重试") time.sleep(RETRY_INTERVAL) connection = get_db_connection() print(f"Oracle数据库版本:{connection.version}") # 插入20000条记录 for i in range(1, 20001): retry_count = 0 insert_success = False while not insert_success: try: # 表不存在、连接超时等异常都会触发重试 cursor = connection.cursor() # 改用参数化查询,避免SQL注入风险,执行效率也更高 sql = "INSERT into SCHEMA.ABC (EVENT_ID, EVENT_TIME) VALUES(:1, CURRENT_TIMESTAMP)" cursor.execute(sql, (i,)) connection.commit() insert_success = True print(f"第{i}条记录插入成功") except cx_Oracle.Error as error: retry_count += 1 print(f"第{i}条记录插入失败,错误信息:{error},当前重试次数:{retry_count}") # 不需要限制重试次数可删除这段判断 if MAX_RETRY_COUNT > 0 and retry_count >= MAX_RETRY_COUNT: print(f"第{i}条记录重试次数超过上限,跳过当前记录,继续插入下一条") break time.sleep(RETRY_INTERVAL) # 重试前先重建连接,避免原有连接失效导致连续失败 try: if connection: connection.close() except: pass connection = get_db_connection() if connection: connection.close()
核心改造点
- 将异常捕获逻辑从外层移到单条插入的逻辑内部,单条插入失败不会终止整个插入循环
- 新增重试机制:插入失败后先等待指定时间,重建数据库连接后再重试,兼容表临时不可用、连接意外断开等多种异常场景
- 原有字符串拼接SQL的写法改为参数化查询,避免SQL注入风险,同时批量执行效率更高
- 可通过调整
MAX_RETRY_COUNT和RETRY_INTERVAL参数适配不同场景,如果对插入成功率要求较高,可以把MAX_RETRY_COUNT设为0,实现无限重试直到插入成功为止
内容的提问来源于stack exchange,提问作者Viral Patel
相关产品推荐
相关产品推荐

