0

I have a tomcat server calling a stored procedure from a jsp. In the stored procedure I have a query that fills a temp table with data. That temp table is then joined to another table over a dblink to fill another temp table using the hint - DRIVING_SITE. The last temp table is then joined to another table on our database to return a resultset to tomcat.

I'm sorry but I can't really provide a code example for all this, but the issue I'm having is this - After a while of the database link not being used, the first query made using the link will do nothing and return the error:

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

Every subsequent query made on the database link within 10 minutes or so of the last call will be fine. The temp table can be huge or small, the amount of data queried seems to make no difference, but the first call after the idle time will get this error probably 75% of the time. Has anyone experienced this issue? If so, are there any resolutions?

The query is structured like so:

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
4

1 回答 1

2

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

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

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

如果修复基础设施不是一种选择,您可以在每次查询后关闭与远程服务器的连接(或至少在每次查询后可能会出现很长的空闲时间)

ALTER SESSION CLOSE DATABASE LINK <<dblink name>>

但是,这意味着您可能会在每次查询时建立和断开与远程服务器的连接——这可能相对昂贵并且可能导致远程服务器上的负载增加(当然,取决于它的频率)发生以及您可能有多少次会话)。

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

于 2013-10-07T22:48:37.590 回答