业务场景:A库上的数据同步到B库上,这个本来是很简单的问题,但由于要在B库上建表,A库只能通过调用B库的存储过程才能实现,就这样就报错了,错误如下:
ORA-02046: 分布式事务处理已经开始
ORA-02063: 紧接着 line (起自 DBLINK_TO_GD)
ORA-06512: 在 "LC_SC_DBLINK_TEST.PKG_SP_ETL_DBLINK_SOUR", line 253
[oracle@oracle ~]$ oerr ora 20463
02046, 00000, "distributed transaction already begun"
// *Cause: internal error or error in external transaction manager.
// A server session received a begin_tran RPC before finishing
// with a previous distributed tran.
在远程调用的存储过程或者包中使用事务控制语句。因为远程调用的包执行时没有机制执行2-phase commit。事务控制语句应该在发起事务的节点执行。
解决方案:
所有的操作在A上执行,可以通过dbms_utility.EXEC_DDL_STATEMENT实现在A上远程DDL,在操作前后都加上。
dbms_session.close_database_link(dblink_name);
exec dbms_utility.EXEC_DDL_STATEMENT@db_link_developer('create table test as select * from dba_objects@dblink_to_A');
--实验参见http://blog.csdn.net/stevendbaguo/article/details/50155845
dbms_session.close_database_link(dblink_name);