在我们的应用程序中,只有在执行后续更新后才会提交数据库更新(当然,两者都使用相同的事务)。但是,我们发现了一个罕见的流程,用户在第二次更新之前退出应用程序,导致第一次丢弃。我正在寻找一种方法来在退出时识别这个未提交的更新。
我知道这样的问题需要重新设计,但这是不可能的。由于流程的罕见性和应用程序的结构,我想知道是否有办法只检查事务本身的未提交更新。
问题对Oracle和SQLServer有效。该应用程序是用PowerBuilder编写的,但如果重要的话,它可以通过各种方式扩展(.NET,Win32等)。
答案 0 :(得分:5)
在Oracle中,您可以调用DBMS_TRANSACTION.local_transaction_id。这将返回当前事务的唯一标识符,如果没有事务处于活动状态,则返回NULL。
分享并享受。
答案 1 :(得分:4)
答案 2 :(得分:2)
如果您使用的是PB11.5并使用自定义事务对象,那么执行非DBMS依赖的操作非常容易。在事务对象的SQLPreview事件中,只需在INSERT,UPDATE或DELETE经过时切换布尔值,然后在COMMIT或ROLLBACK经过时将其关闭。
实际上,如果您正在使用SQLCA,那么交换自定义事务对象并不困难:应用程序,属性,附加属性,变量类型,SQLCA。如果你使用了很多单独的数据库连接和很多“CREATE transaction”语句(标准PB搜索可以找到这个,或者PBL Peeper可以帮助你找到这个单词之间可变数量的空格),那么实现这一点将更难,但并非不可能。
并且,为了完整起见,创建自定义事务对象,File / New / PB Object / Standard Class / Transaction。您有一个常规用户对象,您可以在其中定义实例变量(如我建议的布尔值)和脚本事件(如我建议的SQLPreview事件)和函数(您可能希望为此功能创建一个接口)隐藏详细信息,以备将来扩展时使用。请注意,在11.5之前的Transaction对象上,SQLPreview不可用。 (对于那些认为在11.5之前听起来很熟悉的人,DataWindow实现了一个SQLPreview。)
祝你好运,特里。
答案 3 :(得分:1)
在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。但是,具有相应权限的用户可以将此查询转换为视图并授予对常规joes的访问权限。
感兴趣的是,你还想做什么呢?假设工作单元正确地定义了两个更新,当然只提交一个更新是错误的。如果你想知道的是这种异常终止发生了,那么你需要某种形式的跟踪或记录。
修改强>
Bob Jarvis proposes使用DBMS_TRANSACTION.LOCAL_TRANSACTION_ID()
。这是一个比手工制作的观点更好的建议。 V $ TRANSACTION视图还可用于监视来自其他会话的未提交事务。
答案 4 :(得分:0)
为了便于您的方案的故障排除,您可能希望考虑使用显式命名的本地事务,以及使用“WITH MARK”选项。这允许您将显式事务的名称记录到事务日志中,您可以在以后检查该事务日志,以便识别已发生的事件序列。
请参阅SQL Server联机丛书:Marked Transactions
答案 5 :(得分:0)
在SQL Server中,运行以下命令:
IF @@TRANCOUNT>0 BEGIN
ROLLBACK;
END;
答案 6 :(得分:0)
在SQL Server 2005/2008中,您可以使用DMV。查看this article