ora-02055: distributed update operation failed; rollback required
最近同事遇到一个奇怪的问题求助,以下奉上国外大神的问题重现及解决方法
--------------------------------------------------------------
ora-02055: distributed update operation failed; rollback required
--------------------------------------------------------------
you call a remote procedure or package over a database link.
now, on the other side (the remote side), there was an error encountered, but there were already some statements executed successfully.
now you will need to perform a rollback before you can do a select on the calling side, or you will get this error.
原因:通过数据库链接调用远程存储过程或包。然而,执行过程中远程数据库有报错,,但是部分语句已成功执行
措施:在调用端可以查询之前,需要执行回滚操作,否则将获得以上错误提示。
问题重现:
-- first we create some test users
sql> drop user test1 cascade;
user dropped.
sql> drop user test2 cascade;
sql> create user test1 identified by test1;
user created.
sql> create user test2 identified by test2;
user created.
sql> grant create session, create table, create trigger, create procedure, create database link to test1, test2;
grant succeeded.
sql> alter user test1 quota unlimited on system;
user altered.
sql> alter user test2 quota unlimited on system;
user altered.
now we connect to test 2 (remote user) and create a table
sql> conn test2/test2@xe
connected.
sql> create table test2_tab(n number);
table created.
sql> insert into test2_tab values(1);
1 row created.
sql> commit;
commit complete.
in order to demonstrate this error, we create a trigger on the newly created table, but make sure the trigger fails. in our case, we assign a character to a number field:
create or replace trigger test2_tab_bir
before insert on test2_tab
for each row
begin
:new.n := 'a';
end;
/
trigger created.
connect to test1, create database link
sql> conn test1/test1@xe
connected.
sql>
sql> create database link test2 connect to test2 identified by test2 using 'xe';
database link created.
now we will create a procedure which will first do a successful dml, after that a dml that fails due to the incorrect trigger:
create or replace procedure p is
begin
-- first do a statement that executes ok
update test2_tab@test2 set n=2;
-- next statement will fail because of the invalid trigger
insert into test2_tab@test2 values(1);
end;
/
procedure created.
call the procedure, it will fail:
sql> exec p
begin p; end;
*
error at line 1:
ora-02055: distributed update operation failed; rollback required
ora-06502: pl/sql: numeric or value error: character to number conversion error
ora-06512: at test2.test2_tab_bir, line 2
ora-04088: error during execution of trigger 'test2.test2_tab_bir'
ora-02063: preceding 3 lines from test2
ora-06512: at test1.p, line 4
ora-06512: at line 1
now we have a failed distributed transaction, you need to rollback, else you will get the error when selecting any table/view
sql> select sysdate from dual;
select sysdate from dual
*
error at line 1:
ora-02067: transaction or savepoint rollback required
-- also happens when oracle itself calls another select recursively (notice the ora-00604)
sql> select * from user_2pc_pending;
select * from user_2pc_pending
*
error at line 1:
ora-00604: error occurred at recursive sql level 1
ora-02067: transaction or savepoint rollback required
-----------------------------------
present by dylan.