【问题标题】:Resuming Oracle Database transactions after reconnecting重新连接后恢复 Oracle 数据库事务
【发布时间】:2020-12-11 16:04:19
【问题描述】:

我的任务是稳定遗留应用程序的一部分。这是一个有 20 年历史的 C++ 应用程序,现在使用 Oracle 12.2 数据库进行持久性(即使是 UI 代码)。两者之间的交互是使用 Oracle 调用接口 (OCI) 完成的。
目前,我正在尝试在不正常的断开连接后“修复”数据库事务(例如,在同一网络内从一个接入点更改为另一个接入点)。重新连接到数据库后,我希望客户端从上次会话中恢复事务。这样就不会回滚该事务中的更改。

我相信这将是有益的,因为我无法确定在开始新事务时执行了哪些 DML,哪些未执行。因此,恢复旧的可以查看已经执行的内容。

也许我完全离开了,但我显然愿意接受更好的建议。当然,我似乎找不到某种框架或模式,因为我正在寻找错误的关键字。

最好的问候
一月

【问题讨论】:

  • 事务/会话如何断开然后重新连接?这是什么类型的应用程序?
  • 如果你终止一个会话,oracle 会回滚当前未提交的事务。没了。
  • 是的,@OldProgrammer 所说的:没有办法跨会话桥接未提交的事务。应用程序必须独立于数据库跟踪自己的事务状态。
  • 查看 DBMS_XA,它允许跨会话暂停和恢复事务。如果我有时间,我会发布我曾经做过的 PHP 测试中的 hack 代码。我并不是说这是最好的方法;考虑一个中端解决方案可能会更好。

标签: oracle transactions oracle-call-interface occi


【解决方案1】:

正如我在评论中提到的,DBMS_XA 可能是一种方式,但也许最好考虑替代架构(或修复网络?!)附带条件是您知道连接何时即将断开。

https://www.oracle.com/technetwork/topics/php/highperf-php-preso-405765.pdf的幻灯片 79 中查看我的旧笔记

从架构开始:

drop table mytable;
create table mytable (id number, salary number);
insert into mytable values (1, 100);
insert into mytable values (2, 300);
commit;

然后在三个不同的 SQL*Plus 会话中尝试这三个 sn-ps:

会话 #1

更新第一份工资:

var rc number
exec :rc := DBMS_XA.XA_START(DBMS_XA_XID(123), DBMS_XA.TMNOFLAGS);
update mytable set salary = salary * 1.1 where id = 1;
select * from mytable;
exec :rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUSPEND);

select * from mytable;

查询显示事务暂停后看不到任何变化:

        ID     SALARY
---------- ----------
         1        110
         2        300

        ID     SALARY
---------- ----------
         1        100
         2        300

会话 #2

更新第二份工资:

var rc number
exec :rc := DBMS_XA.XA_START(DBMS_XA_XID(123), DBMS_XA.TMRESUME);
update mytable set salary = salary * 3 where id = 2;
select * from mytable;
exec :rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUSPEND);

select * from mytable;

输出显示可以恢复交易,现在两个工资都在里面更新了。再次挂起事务后,没有任何变化:

        ID     SALARY
---------- ----------
         1        110
         2        900

        ID     SALARY
---------- ----------
         1        100
         2        300

会议 #3

var rc number
exec :rc := DBMS_XA.XA_COMMIT(DBMS_XA_XID(123), TRUE);

select * from mytable;

事务已提交。输出是:

        ID     SALARY
---------- ----------
         1        110
         2        900

【讨论】:

    猜你喜欢
    • 2017-03-23
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2019-05-31
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多