数据库链接连接超时

时间:2013-10-07 21:27:51

标签: sql oracle tomcat oracle10g

我有一个tomcat服务器从jsp调用存储过程。在存储过程中,我有一个用数据填充临时表的查询。然后,临时表通过dblink连接到另一个表,以使用提示 - DRIVING_SITE填充另一个临时表。然后将最后一个临时表连接到我们数据库上的另一个表,以将结果集返回给tomcat。

我很抱歉,但我无法真正提供所有这些的代码示例,但我遇到的问题是这样 - 在数据库链接未使用一段时间后,使用该链接进行的第一个查询将什么也不做,并返回错误:

test.jsp caught exception, closing connection: ORA-02068: following severe error from DATABASE_LINK_NAME
ORA-03135: connection lost contact

在最后一次通话的10分钟左右的时间内对数据库链接进行的每个后续查询都可以。临时表可能很大或很小,查询的数据量似乎没有区别,但是空闲时间之后的第一次调用可能会在75%的时间内得到此错误。有没有人遇到过这个问题?如果是的话,有没有决议?

查询的结构如下:

INSERT INTO temp_table_2
WITH last_submissions AS (
    SELECT /*+ DRIVING_SITE(some_schema.some_table_1) */
           bs.unique_id,
           CASE WHEN COUNT(bs.unique_id) > 1 THEN 'Y' ELSE 'N' END some_flag,
           MAX(trx.unique_id) last_submission
    FROM   (SELECT unique_id
            FROM   temp_table_1) oids,
           some_schema.some_table_1@DATABASE_LINK bs,
           some_schema.some_table_1@DATABASE_LINK trx
    WHERE  oids.unique_id = bs.unique_id
      AND  bs.non_unique_join_id = trx.non_unique_join_id
    GROUP BY bs.unique_id),
something_relevant AS (
    SELECT /*+ DRIVING_SITE(some_schema.some_table_2) */
           last_value_of_something.unique_id,
           last_value_of_something.some_flag,
           mv.value_description status
    FROM   (
        SELECT /*+ DRIVING_SITE(some_schema.some_table_1) */
               ls.unique_id,
               CASE WHEN COUNT(ls.unique_id) > 1 THEN 'Y' ELSE 'N' END some_flag,
               MAX(prd.prd_some_id) last_submission
        FROM   last_submissions ls,
               some_schema.some_table_1@DATABASE_LINK trx,
               some_schema.some_table_2@DATABASE_LINK prd
        WHERE  ls.last_submission = trx.unique_id
          AND  trx.some_unique_id = prd.some_unique_id (+)
        GROUP BY ls.unique_id) last_value_of_something,
        some_schema.some_table_2@DATABASE_LINK prd,
        some_schema.some_table_3@DATABASE_LINK cs,
        some_schema.some_display_value_table@DATABASE_LINK mv
    WHERE  last_value_of_something.last_submission = prd.prd_some_id (+)
      AND  prd.some_id = cs.some_id (+)
      AND  cs.status_code = mv.value (+)
      AND  mv.value_type (+) = 'SOME_INDICATOR_FOR_DISPLAY_VALUES')
SELECT ls.unique_id unique_id,
       NVL(pr.status, trx.some_code) status,
       CASE WHEN ls.some_flag = 'Y' OR pr.some_flag = 'Y' THEN 'Yes' ELSE 'No' END display_the_flag
FROM   /*+ DRIVING_SITE(some_schema.some_table_1) */
       last_submissions ls,
       some_schema.some_table_1@DATABASE_LINK trx,
       something_relevant pr
WHERE  ls.last_submission = trx.unique_id
  AND  ls.unique_id = pr.unique_id

1 个答案:

答案 0 :(得分:2)

您是否希望两个数据库服务器之间的网络稳定并允许连接存在一段时间?

使用数据库链接时,本地服务器会打开与远程服务器的连接。只要您的会话处于打开状态以供其他查询使用,该连接将保持打开状态。如果您看到连接被丢弃,这通常意味着网络中有一些东西(通常是防火墙)正在检测并杀死空闲连接。这也意味着两台服务器之间的网络不稳定。

理想情况下,您可以通过修复任何底层网络问题来解决问题。如果存在阻止空闲连接的防火墙,则应该能够修改防火墙配置以避免例如杀死这些连接。

如果无法修复基础架构,则可以在每次查询后关闭与远程服务器的连接(或者至少在每次查询之后可能需要很长的空闲时间)

ALTER SESSION CLOSE DATABASE LINK <<dblink name>>

然而,这意味着您可能会在每个查询中设置和拆除与远程服务器的连接 - 这可能相对昂贵并且可能导致远程服务器上的更多负载(当然,取决于它发生的频率和你可能有多少会话。

通过数据库链接将数据提取到一系列临时表中以便使用Web应用程序向人类提供数据的整个过程也让我觉得这是一个潜在的问题架构。也许你有充分的理由。但我强烈考虑使用某种复制技术(物化视图,Streams或GoldenGate是内置选项),而不是在运行时通过数据库链接提取数据。