--表:
create table EW_DAYEND_LOG
(
logid VARCHAR2(45),
function_name VARCHAR2(200),
table_name VARCHAR2(200),
data_issue VARCHAR2(7),
log_time DATE,
log_type VARCHAR2(5),
message VARCHAR2(500)
);
--过程:
CREATE OR REPLACE PROCEDURE GET_LOGGER(pDataIssue IN varchar2, --期次
pFunctionName IN varchar2, --方法名称
pTableName IN varchar2, --处理表名称
pType IN varchar2, --0成功 1失败 3异常
vMsg IN varchar2) is --处理信息
--插入日志
BEGIN
INSERT INTO EW_DAYEND_LOG
(LOGID, FUNCTION_NAME, TABLE_NAME, DATA_ISSUE, LOG_TIME, LOG_TYPE, MESSAGE)
VALUES
(SYS_GUID(),
pFunctionName ,
pTableName ,
pDataIssue ,
SYSDATE,
pType ,
vMsg );
COMMIT;
END GET_LOGGER;
--包
create or replace package day_end_test is
function day_end(pDataIssue in varchar2) return varchar2;
end day_end_test;
/
CREATE OR REPLACE PACKAGE BODY day_end_test is
function day_end (pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
GET_LOGGER(pDataIssue, 'day_end_test', 'log', '0', '调用测试');
/* INSERT INTO EW_DAYEND_LOG
(LOGID, FUNCTION_NAME, TABLE_NAME, DATA_ISSUE, LOG_TIME, LOG_TYPE, MESSAGE)
VALUES
(SYS_GUID(),
'day_end_test' ,
'log' ,
pDataIssue,
SYSDATE,
'0',
'调用测试1');
COMMIT;*/
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER(pDataIssue, 'day_end_test', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test;
/
2.1.2 B服务器12 准备- dblink、包
创建dblink:ew_14
创建包:day_end_test2
复制代码
--创建dblink
create public database link ew_14
connect to xxx identified by xxx
using '192.168.3.14/orcl';
--包
create or replace package day_end_test2 is
function day_end_run(pDataIssue in varchar2) return varchar2;
end day_end_test2;
/
CREATE OR REPLACE PACKAGE BODY day_end_test2 is
function day_end_run(pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
GET_LOGGER@ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '0', '12调用测试');
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER@Ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test2;
/
--修改包体:改为调用远程包
CREATE OR REPLACE PACKAGE BODY day_end_test2 is
function day_end_run(pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
--GET_LOGGER@ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '0', '12调用测试');
vResult := day_end_test.day_end@ew_14(pDataIssue);
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER@Ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test2;
再次测试:返回1 报错
报错:ORA-02064: 不支持分布式操作
19行就是插入commit 的时候。
至此,问题复现。
2.3 实验解决
2.3.1 修改A服务器14的包 测试no
修改A服务器14的包:将包中的存储过程注释调 ,改为直接插入表,再测试
复制代码
CREATE OR REPLACE PACKAGE BODY day_end_test is
function day_end (pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
--GET_LOGGER(pDataIssue, 'day_end_test', 'log', '0', '调用测试');
INSERT INTO EW_DAYEND_LOG
(LOGID, FUNCTION_NAME, TABLE_NAME, DATA_ISSUE, LOG_TIME, LOG_TYPE, MESSAGE)
VALUES
(SYS_GUID(),'day_end_test' ,'log' , pDataIssue,SYSDATE, '0','调用测试33');
COMMIT;
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER(pDataIssue, 'day_end_test', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test;
在B服务器调用A的包,测试结果:依然报错 ORA-02064: 不支持分布式操作
说明: 调用远端包不可以,调用远端存储过程可以。
2.3.2 增加A服务器含包的存储过程 测试 no
复制代码
--增加存储过程
CREATE OR REPLACE PROCEDURE PRO_TEST(pDataIssue IN varchar2,
vResult OUT varchar2) is
BEGIN
vResult := day_end_test.day_end(pDataIssue);
END PRO_TEST;
本地测试:ok
远端调用b:依然报错
复制代码
--修改远端调用包:改为调用存储过程
CREATE OR REPLACE PACKAGE BODY day_end_test2 is
function day_end_run(pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
--GET_LOGGER@ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '0', '12调用测试');
--vResult := day_end_test.day_end@ew_14(pDataIssue);
PRO_TEST@ew_14(pDataIssue,vResult);
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER@Ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test2;
测试结果:报错 ORA-02064: 不支持分布式操作
2.3.3 解决思路1:被调用的不要commit
解决思路:被调用的不要commit,rollback等数据库事务操作,统一在服务端执行。
服务器A 14 被调用端:代码注释commit。服务器B 12 调用端,增加commit;
代码修改如下:
复制代码
--服务器A 被调用端,去掉commit
CREATE OR REPLACE PACKAGE BODY day_end_test is
function day_end (pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
--GET_LOGGER(pDataIssue, 'day_end_test', 'log', '0', '调用测试');
INSERT INTO EW_DAYEND_LOG
(LOGID, FUNCTION_NAME, TABLE_NAME, DATA_ISSUE, LOG_TIME, LOG_TYPE, MESSAGE)
VALUES
(SYS_GUID(),'day_end_test' ,'log' , pDataIssue,SYSDATE, '0','调用测试33');
--COMMIT;
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER(pDataIssue, 'day_end_test', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test;
--服务器b 12上:增加commit
CREATE OR REPLACE PACKAGE BODY day_end_test2 is
function day_end_run(pDataIssue in varchar2) return varchar2 is
vResult varchar2(10);
vMsg varchar2(1000);
begin
vResult := '0';
BEGIN
--GET_LOGGER@ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '0', '12调用测试');
vResult := day_end_test.day_end@ew_14(pDataIssue);
--PRO_TEST@ew_14(pDataIssue,vResult);
commit;
EXCEPTION
WHEN OTHERS THEN
vMsg := '报错位置:' || dbms_utility.format_error_backtrace || '报错信息:' ||
substr(SQLERRM, 1, 200);
GET_LOGGER@Ew_14(pDataIssue, 'day_end_test2.day_end_run@12', 'log', '3', vMsg);
vResult := '1';
END;
return vResult;
end;
end day_end_test2;