author:skate
time:2009/02/17
为了提高数据库性能和长远计划,决定把出票这一功能独立做一个数据库,但出票库和交易库又要保持数据的同步
我采用了触发器和定时执行procedure来完成这一功能,起初是把出票库和交易库放在一个数据库里,只是在不同的
schema (tickets)里,这样的结构已经在线上正常运营了,现在要把tickets单独放到一台数据库服务器上。这几天
单独做了一个数据库服务器,放在测试环境来测试,两个库之间的通信采用dblink。在这一过程中遇到一个问题
ORA-02289: sequence does not exist
ORA-02063: 紧接着 line (起自 TO_TICKETS)
ORA-06512: 在 "user.TRI_TB_MATCH_AIUR", line 28
ORA-04088: 触发器 'user.TRI_TB_MATCH_AIUR' 执行过程中出错
经过查证是因为在用dblink的时候,同时用到序列引起的,为此总结下这个问题
在使用dblink和序列的时候应该注意几个问题
1。 在向远端插入数据
1.从本地表中读取数据,并引用本地序列
SQL> insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_test4;
insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_test4
*
ERROR 位于第 1 行:
ORA-02289: 序列(号)不存在
ORA-02063: 紧接着line(源于TEST4)
ORA-02063: 紧接着2 lines(源于YANGTK)
2.从本地表中读取数据,但访问远端序列
SQL> insert into test_on_yangtk@yangtk select seq_on_yangtk.nextval@yangtk from test_on_test4;
已创建 1 行。
SQL> rollback;
回退已完成。
3.读取远端数据表中数据,同时访问远端序列。
SQL> insert into test_on_yangtk@yangtk select seq_on_yangtk.nextval@yangtk from test_on_yangtk@yangtk;
已创建 1 行。
SQL> rollback;
回退已完成。
4.读取远端数据表中数据,但是访问本地序列。
SQL> insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_yangtk@yangtk;
insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_yangtk@yangtk
*
ERROR 位于第 1 行:
ORA-02289: 序列(号)不存在
ORA-02063: 紧接着line(源于TEST4)
ORA-02063: 紧接着2 lines(源于YANGTK)
从上面的结果来看,通过dblink向远端表插入数据的时候,最好用远端库上的序列或者在远端库上要建立
一个到本地dblink
Oracle的error文档上这样描述2289错误的:
ORA-02289 sequence does not exist
Cause: The specified sequence does not exist, or the user does not have the required privilege to perform this operation.
Action: Make sure the sequence name is correct, and that you have the right to perform the desired operation on this sequence.
根据目前的错误以及Oracle给出的错误原因,初步怀疑对于这种插入远端数据表的分布式事务,实际上是在远端上执行的。
因此YANGTK上的scott用户找不到SEQ_ON_TEST4这个序列。
给YANGTK上的scott用户增加一个指向TEST4上yangtk用户的数据库链。
SQL> conn scott/tiger@yangtk
已连接。
SQL> create database link test4 connect to yangtk identified by yangtk using 'test4';
数据库链接已创建。
SQL> conn yangtk/yangtk@test4
已连接。
SQL> insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_test4;
已创建 1 行。
SQL> rollback;
回退已完成。
SQL> insert into test_on_yangtk@yangtk select seq_on_test4.nextval from test_on_yangtk@yangtk;
已创建 1 行。
SQL> rollback;
回退已完成。
我的解决方法是用远端数据库的序列
如果在一条语句中同时使用数据库链和序列,这时候应当小心,
你可能不仅需要一条到远端的数据库链,还可能需要一个从远端到本地的数据库链。
参考文档 :
http://tech.it168.com/db/o/2006-11-20/200611201706525_2.shtml
---end----