Oracle 甲骨文:如何找出是否有一个交易悬而未决?
我正在寻找一种方法来确定当前会话中是否有未限制的INSERT、UPDATE或DELETE语句。一种方法是使用当前sid检查v$lock,但这需要对v$lock进行读取访问,如果DBA不想授予它,这将是一个问题。除了跟踪应用程序发出的所有数据库命令之外,还有其他方法吗Oracle 甲骨文:如何找出是否有一个交易悬而未决?,oracle,transactions,Oracle,Transactions,我正在寻找一种方法来确定当前会话中是否有未限制的INSERT、UPDATE或DELETE语句。一种方法是使用当前sid检查v$lock,但这需要对v$lock进行读取访问,如果DBA不想授予它,这将是一个问题。除了跟踪应用程序发出的所有数据库命令之外,还有其他方法吗 SELECT * FROM V$TRANSACTION WHERE STATUS='ACTIVE'; 见: 您可以检查您的会话是否在V$TRANSACTION中有一行显然需要此视图的读取权限: SQL> SELECT COU
SELECT * FROM V$TRANSACTION
WHERE STATUS='ACTIVE';
见:
您可以检查您的会话是否在V$TRANSACTION中有一行显然需要此视图的读取权限:
SQL> SELECT COUNT(*)
FROM v$transaction t, v$session s, v$mystat m
WHERE t.ses_addr = s.saddr
AND s.sid = m.sid
AND ROWNUM = 1;
COUNT(*)
----------
0
SQL> insert into a values (1);
1 row inserted
SQL> SELECT COUNT(*)
FROM v$transaction t, v$session s, v$mystat m
WHERE t.ses_addr = s.saddr
AND s.sid = m.sid
AND ROWNUM = 1;
COUNT(*)
----------
1
SQL> commit;
Commit complete
SQL> SELECT COUNT(*)
FROM v$transaction t, v$session s, v$mystat m
WHERE t.ses_addr = s.saddr
AND s.sid = m.sid
AND ROWNUM = 1;
COUNT(*)
----------
0
另见
这是我通常使用的查询
select s.sid
,s.serial#
,s.username
,s.machine
,s.status
,s.lockwait
,t.used_ublk
,t.used_urec
,t.start_time
from v$transaction t
inner join v$session s on t.addr = s.taddr;
使用下面的查询查找挂起的事务 如果它返回一个值,则表示有一个挂起的事务 以下是查询: 从dual中选择dbms_transaction.step_id 参考资料:
Matthew Watson可以修改为在RAC中使用
select t.inst_id
,s.sid
,s.serial#
,s.username
,s.machine
,s.status
,s.lockwait
,t.used_ublk
,t.used_urec
,t.start_time
from gv$transaction t
inner join gv$session s on t.addr = s.taddr;
最简单和最可靠的解决方案是尝试并启动一个事务,看看它是否成功。如果一些代码已经启动了一个事务,但是还没有发布任何DML,那么V$transaction视图将不会显示任何内容 在下面的示例中,我处理异常以引发用户定义的应用程序错误。要遵从现有的异常处理程序,只需执行一个SET事务,然后立即提交以撤消它
DECLARE
transaction_in_progress EXCEPTION;
PRAGMA EXCEPTION_INIT(transaction_in_progress, -1453);
BEGIN
SET TRANSACTION NAME 'CHECK_FOR_TRANSACTION_ALREADY_SET';
COMMIT; -- end transaction
EXCEPTION
WHEN transaction_in_progress THEN
RAISE_APPLICATION_ERROR(-20000,'Transaction is already in progress');
END;
/
我假设您没有访问任何V$视图的权限。对于未提交的事务,我们还可以获取sql_文本的可能副本。:-不同的描述。。。未提交的工作与挂起的事务工作得非常好,我还需要在使用ALTER SYSTEM kill会话'sid,serial'后终止非活动事务;有些情况下,此方法不起作用,返回误报:例如,如果您只是使用数据库链接select*from从远程数据库中选择数据remotetable@databaselink即使您没有更改任何数据,oracle也会启动事务。此方法不能保证您有未提交的数据。。。您知道如何改进此查询以过滤掉此类事务吗?这真的让我很困惑。@CarloSirna是的,在有些情况下,即使您不更改数据,Oracle也会启动事务。连接到远程数据库就是一个例子,请参见示例。一个简单的选择。。。FOR UPDATE还将在不修改数据的情况下启动事务。我的回答中描述的方法告诉您是否有待处理的事务,而不是是否有未提交的数据。这两种方法并不等同。修改数据就足够了,但启动事务时不需要。请执行一个设置事务,然后运行您的查询。@PeterNosko:您建议的解决方案工作得很好,但与简单的select dbms_transaction.step_id from dual相比非常复杂;正如DBA所建议的那样。步骤id返回:如果没有事务,则返回NULL;如果事务存在但为空,则返回0;如果有任何挂起的更改,则返回非NULL、非零值。这比你的版本简单得多,告诉我们更多关于连接状态的信息。您是否发现step_id有任何问题导致其不可靠?