在这里插入图片描述

概念:

大意就是,通过dblink连接另一个数据库的表是,对另一个数据库的表进行dml操作,同时也可能在同一个事务中对本库中的本地表做事务提交操作,那么对于dblink的表,需要确保远端的数据库也要提交,那么在本地像远端确认提交的时候,先由本地库发一个prepare的确认信息,远端回复prepare了以后,本地在执行commit信息;此种情况就是在本地执行commit以后,此时远端库还没有完全commit,此时网络中断,导致本地库该表是commit状态,但是远端库还是prepare状态,一般来讲,此时如果源端得到的事务信息是全的,那么数据库不需要人为干预,能够自动根据事务信息进行提交操作,但是出现这个问题的时候,基本就表示提交的事务信息不足以让远端库执行提交操作,所以此时这种事务就需要人为干预了。

视图:

dba_2pc_pending
dba_2pc_neighbors

1.查看

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;
或者查*,更全
在这里插入图片描述

1.collecting:在收集数据过程中,产生异常
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;

2.prepared: 在接受到异步commit/rollback指令前, 产生异常
解决方法:
rollback force tran_id
commit force tran_id; – 可根据异步transaction的状况决定使用方法。

拼接:

select 'rollback force  ''' || LOCAL_TRAN_ID || ''';' || chr(10) ||
'execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(''' || LOCAL_TRAN_ID
 || ''');' || chr(10) || 'commit;' from DBA_2PC_PENDING;

3.forced rollback: 在使用rollback force出现
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;

4.forced commit:在使用commit force出现
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;

2.prepared解决不了的情况

查询该事务表是否有活动事务

SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;

2.1如果没有活动事务

set transaction use rollback segment SYSTEM;
delete from sys.pending_trans$ where local_tran_id ='11.4.419599' ;
delete from sys.pending_sessions$ where local_tran_id = '11.4.419599';
delete from sys.pending_sub_sessions$ where local_tran_id = '11.4.419599';
commit;

2.2如果有活动事务
尝试purge失败
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;
在这里插入图片描述

删除数据字典中分布式事务信息

delete from sys.pending_trans$ where local_tran_id = '11.4.419599';
delete from sys.pending_sessions$ where local_tran_id = '11.4.419599';
delete from sys.pending_sub_sessions$ where local_tran_id ='11.4.419599';
commit;

禁用自动分布式恢复
alter system disable distributed recovery;

根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)

INSERT INTO pending_trans$
            (local_tran_id,
             global_tran_fmt,
             global_oracle_id,
             state,
             status,
             session_vector,
             reco_vector,
             type#,
             fail_time,
             reco_time)
VALUES     ( '11.4.419599', /* <== Replace this with your local tran id */
             306206,
             '123.12345.1.2.3',
             'prepared',
             'p',
             Hextoraw('00000001'),
             Hextoraw('00000000'),
             0,
             sysdate,
             sysdate );
 
INSERT INTO pending_sessions$
VALUES     ( '11.4.419599',/* <==replace only this with your local tran id */
             1,
             Hextoraw('05004f003a1500000104'),
             'c',
             0,
             30258592,
             '',
             146 );
             
             
commit ;

回滚事务
rollback force ‘11.4.419599’;

重新启用自动分布式事务恢复
alter system enable distributed recovery;

再次查看state,已经不是prepared

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';

清理没用的事务信息
exec dbms_transaction.purge_lost_db_entry(‘11.4.419599’);

解决

3.分布式事务存在,dba_2pc(pending表)视图中没有数据

遇到ORA-2054, ORA-1591等错误,但是dba_2pc_pending没记录。
这种情况,commit force还是rollback force都会报
ORA-02058: no prepared transaction found with ID 10.20.360
一样的方式,将基表数据补齐。

1.dba_2pc_pending是否没记录
select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;

2.确认该事务表是否有活动事务

SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;

3.禁用自动分布式恢复
alter system disable distributed recovery;

4.根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)

INSERT INTO pending_trans$
            (local_tran_id,
             global_tran_fmt,
             global_oracle_id,
             state,
             status,
             session_vector,
             reco_vector,
             type#,
             fail_time,
             reco_time)
VALUES     ( '11.4.419599', /* <== Replace this with your local tran id */
             306206,
             '123.12345.1.2.3',
             'prepared',
             'p',
             Hextoraw('00000001'),
             Hextoraw('00000000'),
             0,
             sysdate,
             sysdate );
 
INSERT INTO pending_sessions$
VALUES     ( '11.4.419599',/* <==replace only this with your local tran id */
             1,
             Hextoraw('05004f003a1500000104'),
             'c',
             0,
             30258592,
             '',
             146 );
             
             
commit ;

5.回滚事务
rollback force ‘11.4.419599’;

6.重新启用自动分布式事务恢复
alter system enable distributed recovery;

7.再次查看state,已经不是prepared

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';

8.清理没用的事务信息
exec dbms_transaction.purge_lost_db_entry(‘11.4.419599’);

解决

Logo

更多推荐