如何使用XA数据源和事务关闭JDBC中的Oracle DbLink以避免ORA-02020错误?

时间:2011-02-23 09:17:05

标签: oracle jdbc dblink

我有一个基于JDBC的应用程序,它使用跨越多个连接的XA数据源和事务,连接到Oracle数据库。应用程序有时需要使用共享DbLink使用来自另一个(Oracle)服务器的表的连接来进行一些查询。如果我不经常这样做,请求有效,但是在快速连续4或5次请求后,我收到错误(ORA-02020 - 使用的链接太多)。我做了一些研究,建议的补救措施是打电话给“ALTER SESSION CLOSE DATABASE LINK”。如果我在加入DbLnk表的查询后调用此请求,则会收到错误ORA-2080(链接正在使用中)。如果我在查询之前调用它,我会得到ORA-2081(链接已关闭)。这个电话有什么好处吗? JDBC连接在事务提交之前很久就关闭了(由servlet或EJB容器管理,具体取决于具体情况)。我得到的印象是,当连接关闭时,Oracle会将链接标记为已关闭,但它需要一两分钟才能返回到可用链接池。我知道我可以扩大链接池(使用配置文件中的open_links属性),但这并不能保证在较重的负载下我不会遇到同样的问题。有什么我可以采取不同的方式让dblinks更快地关闭?

1 个答案:

答案 0 :(得分:2)

任何分布式SQL(甚至是select)都会打开一个必须先关闭的事务,然后才能关闭数据库链接。在调用ALTER SESSION CLOSE DATABASE LINK之前,您需要回滚或提交。

但听起来你已经有了处理交易的其他事情。如果无法手动回滚或提交,则应尝试增加打开的链接数。 OPEN_LINKS参数是每个会话的最大链接数。您需要的链接数量实际上并不依赖于负载,它应该基于不同远程数据库的最大数量。

修改

您在评论中描述的情况不应该发生。我对你的系统了解不够,不知道交易真的发生了什么。无论如何,如果你无法弄清楚系统究竟在做什么,你可以用这样的程序替换“alter session close database link”:

create or replace procedure rollback_and_close_db_links authid current_user is
begin
    rollback;
    for links in (select db_link from v$dblink) loop
        execute immediate 'alter session close database link '||links.db_link;
    end loop;
end;
/

你可能需要这笔补助金:

grant select on v_$dblink to [relevant user];