问题引入:当发生网络波动时,数据库连接断开,导致无法完成数据库重连。

原因:sqlalchemy采用的是连接池技术,客户端程序获取的连接对象(session)其实是连接池物理连接的一个句柄,当网络断开后,客户端未通过安全方式删除连接对象与池中对象之前的联系,导致无法重新获取连接句柄。

解决方案也很简单,在每次执行完sql语句后主动断开连接对象与池中对象的联系即可,代码示例:

while True:
now_time = time.strftime("%F %H:%M:%S", time.localtime())
try:
query = oracle_conn.execute("需要执行的sql语句").fetchall()
print(now_time, oracle_conn, query)

except Exception as e:
print(f"{now_time}: 数据库连接异常,详情:{e}")
# 在数据库抛出异常后需将连接关闭,
# 可解决由于网络波动导致数据库连接断开报“Can't reconnect until invalid transaction is rolled back”的问题

# close()方法可在抛异常的时候调用,也可以每次调用,如果每次调用需在commit()之后调用
oracle_conn.close()
# 如果执行的为insert、update、delete语句,需做一次提交,避免锁表或锁行
# oracle_conn.commit()
time.sleep(2)

这只是个初步解决方案,我相信还有更好的解决方案,希望可以探讨一下

打赏

发表评论

邮箱地址不会被公开。 必填项已用*标注