【问题标题】:Telling if a transaction has uncommitted updates判断事务是否有未提交的更新
【发布时间】:2010-12-29 01:28:26
【问题描述】:

在我们的应用程序中,只有在执行后续更新后才会提交数据库更新(当然,两者都使用相同的事务)。但是,我们发现了一种罕见的流程,即用户在第二次更新之前退出应用程序,导致第一次被丢弃。我正在寻找一种在退出时识别此未提交更新的方法。

我知道这样的问题需要重新设计,但这是不可能的。由于流程的稀有性和应用程序的结构,我想知道是否有办法只检查事务本身是否有未提交的更新。

问题对 Oracle 和 SQLServer 有效。该应用程序是用 PowerBuilder 编写的,但如果需要,它可以通过各种方式(.NET、Win32 等)进行扩展。

【问题讨论】:

    标签: sql-server oracle transactions commit powerbuilder


    【解决方案1】:

    这可能会有所帮助

    @@TRANCOUNT (Transact-SQL)

    返回活跃的数量 当前的交易 连接。

    【讨论】:

    • 我以为那只是 SQL Server?
    【解决方案2】:

    为了便于对您的方案进行故障排除,您可能希望考虑使用显式命名的本地事务以及使用“WITH MARK”选项。这允许您将显式事务的名称记录到事务日志中,当然您可以在稍后阶段对其进行检查,以确定已发生的事件序列。

    请参阅 SQL Server 联机丛书:Marked Transactions

    【讨论】:

      【解决方案3】:

      在 Oracle 中有一个视图 V$TRANSACTION,其中包含每个未提交事务的行。没有从外部查看该事务性质的机制(除非您在代码中内置了检测工具,例如通过使用 DBMS_APPLICATION_INFO.SET_MODULE() )。但是,当前会话可以查看它是否有未提交的工作,如下所示:

      SQL> select t.status
        2  from   v$transaction t
        3         join v$session s
        4         on s.saddr = t.ses_addr
        5  where s.sid = sys_context('userenv', 'sid')
        6  /
      
      STATUS
      ----------------
      ACTIVE
      
      SQL>
      

      如果没有未提交的事务,则此查询将返回 NO_DATA_FOUND。默认情况下,V$ 视图不会授予用户,因为它们实际上是 DBA thang。但是,具有适当权限的用户可以将此查询转换为视图并授予对常规 joes 的访问权限。

      出于兴趣,无论如何,您想做什么?假设工作单元在两次更新中被正确定义,那么只提交一次肯定是错误的。如果您只想知道发生了这种异常终止,那么您需要某种形式的跟踪或日志记录。

      编辑

      鲍勃·贾维斯proposes 使用DBMS_TRANSACTION.LOCAL_TRANSACTION_ID()。这是一个比手工视图更好的建议。 V$TRANSACTION 视图也可用于监控来自其他会话的未提交事务。

      【讨论】:

      • 嗯,这两个更新并不是一个真正的工作单元。未提交的更新实际上是对外部服务器的重新路由调用,而不是被传输,而是存储在数据库中。我们的应用程序在提交方面具有一致的行为,但更新来自应用程序的不同部分。单独的交易可能是合适的,但这也将是很多工作。所以,提交一个未提交的更新应该没问题。
      【解决方案4】:

      在 Oracle 中,您可以调用 DBMS_TRANSACTION.local_transaction_id。这将返回当前事务的唯一标识符,如果没有事务处于活动状态,则返回 NULL。

      分享和享受。

      【讨论】:

        【解决方案5】:

        在 SQL Server 中,运行:

        IF @@TRANCOUNT>0 BEGIN
          ROLLBACK;
        END;
        

        【讨论】:

          【解决方案6】:

          如果您在 PB11.5 上并使用自定义事务对象,则很容易做一些不依赖于 DBMS 的事情。在事务对象的 SQLPreview 事件中,只需在 INSERT、UPDATE 或 DELETE 过去时打开一个布尔值,然后在 COMMIT 或 ROLLBACK 过去时将其关闭。

          实际上,如果您使用 SQLCA,那么在自定义事务对象中交换并不难:应用程序、属性、附加属性、变量类型、SQLCA。如果您正在使用带有大量“创建事务”语句的大量单独数据库连接(标准 PB 搜索可以找到这个,或者PBL Peeper 可以帮助您找到这个单词之间有可变数量的空格),然后实现这个会更难,但并非不可能。

          并且,为了完整起见,创建一个自定义事务对象,File / New / PB Object / Standard Class / Transaction。您有一个常规用户对象,您可以在其中定义实例变量(如我建议的布尔值)和脚本事件(如我建议的 SQLPreview 事件)和函数(您可能希望为此功能创建一个接口隐藏详细信息,以防您将来想扩展它)。请注意,SQLPreview 在 11.5 之前的 Transaction 对象上不可用。 (对于那些认为在 11.5 之前听起来很熟悉的人,DataWindow 实现了 SQLPreview。)

          祝你好运,

          特里。

          【讨论】:

          • 我没有在事务的 SQL 预览中获得 COMMIT 或 ROLLBACK。 PB 12.5,ODBC 连接。这真的让我很沮丧,因为我制作了一个漂亮的 SQL Spy 式窗口,它显示所有进入数据库的 SQL,如果有未提交的事务,则将一个大指示条变为红色。
          【解决方案7】:

          在 SQL Server 2005/2008 中,您可以使用 DMV。查看this article

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多