标签:
最近一个同事咨询,说有一个含有dblink的SQL,在plsql中这个SQL可以正常执行,而在JAVA后台调用执行这个SQL执行要报错:
ORA-24777:不允许使用不可移植的数据库链路。
请同事跟踪程序进去后,发现是通过dblink查询某个远程库表,而且使用了XA分布式事务数据库连接。
以前也知道XA有不少坑,都绕着走了。
但这次既然遇到了,就准备解决了方便以后,有个统一的解决方案。
去查了下metalink,恰好有一篇文章提到这个问题:ORA-24777 reported when using a database link from within an XA coordinated transaction (文档 ID 1506756.1)
这个可能是一个bug,或者说是JDBC的一个坑,使用JDBC然后调用有dblink的分布式事务,可能会出现这个问题。
metalink提供了两种方案解决ORA-24777:
1.把oracle服务器模式设置成shared server;
ALTER SYSTEM SET DISPATCHERS="(PROTOCOL=TCP)" scope=both;
ALTER SYSTEM SET SHARED_SERVERS = 10 scope=both;
2.把dblink连接设置成shared模式。
第一种解决方案的影响较大,也有可能带来其他问题出现。第二种成本低,对于系统本身影响小。因此建议选择方案二。
常用类型的dblink都会很容易创建,这儿来说说怎么创建shared的dblink
我们先来看看create database link的语法:
CREATE [SHARED][PUBLIC] database link link_name
[CONNECT TO [user][current_user] IDENTIFIED BY password]
[AUTHENTICATED BY user IDENTIFIED BY password]
[USING ‘connect_string‘]
说明:
(1) 权限:创建数据库链接的帐号必须有CREATE DATABASE LINK或CREATE PUBLIC DATABASE LINK的系统权限,用来登录到远程数据库的帐号必须有CREATE SESSION权限。
一个公用数据库链接对于数据库中的所有用户都是可用的,而一个私有链接仅对创建它的用户可用,切不能被授权使用。
(2)link : 当source端的数据库GLOBAL_NAME=TRUE时,link名必须与远程数据库的全局数据库名global_name相同;否则,可以任意命名。
(3)current_user : 使用该选项是为了创建global类型的dblink。在分布式体系中存在多个数据库的时候,如果想要在每一个数据库中都可以使用同样的名字来访问数据库test,那在每个数据库中都要创建一个到数据库test的db_link,太麻烦了,所以现在有这个选项。只要创建一次,所有的数据库都可以使用这个db_link来访问了。要使用这个特性,必须有oracle nameserver或者ORACLE目录服务器。并且数据库test的参数global_names=true.
(4)connectstring:连接字符串,tnsnames.ora中定义远程数据库的连接串,也可以在创建dblink的时候直接指定,类似ezconnect。
(5)username、password:远程数据库的用户名,口令。如果不指定,则使用当前的用户名和口令登录到远程数据库,当创建connected user类型的dblink时,需要如果采用数据字典验证,则需要两边数据库的用户名密码一致。
对于shared dblink
其中建一个shared 的数据库连接,同时要指定database link_authentication。
使用shared方式的 database link是数据库会限制到远程数据库的连接的数量,这样以避免过多的连接对远程数据库造成太大的压力。
在使用shared database link的时候,到database link的连接会在连接以后与本地连接断开,为防止未授权的session使用此链接而要求在创建shared database link的时候必须要指定database link_authentication。
(from Oracle document: A shared database link is a link between a local server process and the remote database. The link is shared because multiple client processes can use the same link simultaneously.)
如下命令建立一个shard dblink:
CREATE SHARED PUBLIC database link
sales.us.americas.acme_auto.com
CONNECT TO scott IDENTIFIED
BY tiger AUTHENTICATED BY
anupam IDENTIFIED BY bhide USING ‘sales‘;
其中
Connects To Database:sales using net service name sales
Connects As:scott using password tiger, authenticated as anupam using password bhide
使用AUTHENTICATED BY子句稍微有些困扰,但是由于实现共享链接的方式安全性决定它是必须的。这个例子中的用户名和口令anupam/bhide必须在远程系统上有效。
再举例说明一下:
示例1
CREATE SHARED DATABASE_LINK DB_LINK_NAME
CONNECT TO REMOTE_USER_NAME_1 IDENTIFIED BY USER_PASSWORD_1
AUTHENTICATED BY REMOTE_USER_NAME_2 IDENTIFIED BY USER_PASSWORD_2
USING ‘192.168.0.157:1521/SID‘
示例2
CREATE SHARED DATABASE_LINK DB_LINK_NAME
AUTHENTICATED BY REMOTE_USER_NAME_2 IDENTIFIED BY USER_PASSWORD_2
USING ‘192.168.0.157:1521/SID‘
注意,示例1中出现两个REMOTE_USER_NAME分别是REMOTE_USER_NAME_1\REMOTE_USER_NAME_2,因为指定了SHARED关键字必须要求有AUTHENTICATION而这时CONNECT TO可以省略(如示例2)。
创建完shared database link之后,jdbc执行这个SQL报错的问题解决。
但另外一个问题又来了:每一个dblink有连接限制(默认是4),如果超过连接限制数,会报错:ORA-02020: too many database links in use
1.查看相关初始化参数:
SQL> show parameters open_links;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
open_links integer 4
open_links_per_instance integer 4
两个的含义:
OPEN_LINKS_PER_INSTANCE specifies the maximum number of migratable open connections globally for each database instance. XA transactions use migratable open connections so that the connections are cached after a transaction is committed. Another transaction can use the connection, provided the user who created the connection is the same as the user who owns the transaction.
OPEN_LINKS_PER_INSTANCE is different from OPEN_LINKS, which indicates the number of connections from a session. The OPEN_LINKS parameter is not applicable to XA applications.
中文解释一下:
open_links:oracle的官方解释是每个session最多允许的dblink数量;
open_links_per_instance这个参数是指每个实例最多允许的dblink个数。
2.修改open_links
alter system set open_links=255 scope=spfile;
alter system set open_links_per_instance=255 scope=spfile;
3.使修改后重启数据库生效
弄清 ORA-24777:不允许使用不可移植的数据库链路 产生的原因,以及解决方法
标签:
原文地址:http://www.cnblogs.com/suredandan/p/5737453.html