cx_Oracle 中的 Python 长时间空闲连接获取:DPI-1080:连接被 ORA-3113 关闭

问题描述 投票:0回答:1

我正在运行长时间运行的 Python 可执行文件。 启动时使用 cx_Oracle 打开 Oracle 连接。 空闲连接超过 45-60 分钟后 - 出现此错误。 cx_Oracle 中需要任何想法或特殊设置吗?

python oracle-database network-programming cx-oracle
1个回答
7
投票

不要在应用程序中保留未使用的连接,而是考虑在不需要时将其关闭,然后在需要时重新打开。 建议使用连接池,因为池可以处理一些底层故障(例如您的故障),并为您提供可用的连接。

在应用程序初始化时启动池一次:

import oracledb 

pool = oracledb.create_pool(user="username", password=pw, 
                  dsn="localhost/orclpdb1", min=0, max=4, increment=1)

然后获取连接并仅在需要时保持连接:

with pool.acquire() as connection:
    cursor = connection.cursor()
    for result in cursor.execute(
             """select sys_context('userenv','sid') from dual"""):
        print(result)

with
块的结尾会将连接释放回池中。 它 不会被摧毁。 下次调用
acquire()
时,池可以检查 连接仍然可用。 如果不是,它会给你一个新的。 由于这些检查,即使您只有一个连接,该池也很有用。

请参阅我的博客文章 始终使用连接池 — 并且 如何 其中大部分适用于 cx_Oracle。

但是如果您不想更改代码,请尝试设置 Oracle 网络参数

EXPIRE_TIME
,如 python-oracledb 文档中所示。 这可以在不同的地方设置。

使用 python-oracledb 的精简模式,您可以在创建连接或池时传递

expire_time
参数,例如:

pool = oracledb.create_pool(user="username", password=pw, 
                            dsn="dbhost.example.com/orclpdb",
                            min=0, max=4, increment=1
                            expire_time=4)

在python-oracledb的Thick模式下:

  • 使用 18c 客户端库,可以将其作为
    (EXPIRE_TIME=n)
    添加到连接描述符的描述部分
  • 借助 19c 客户端库,还可以通过 Easy Connect 使用:
    host/service?expire_time=n
  • 使用 21c 客户端库,它还可以在客户端 sqlnet.ora 文件中使用

如果使用 EXPIRE_TIME 来防止防火墙终止空闲 连接数,那么该值应该小于防火墙超时时间的一半。

这可能并不总是有帮助,具体取决于关闭连接的原因。

从根本上讲,您应该/可以修复根本原因,这可能是防火墙超时、DBA 强加的用户资源或数据库空闲时间限制。

© www.soinside.com 2019 - 2024. All rights reserved.