请在文档
中解释此段落
WAITANY
程序。如果使用WAITANY
过程,并且信令会话发出信号但在信号的一秒内没有提交,则需要轮询循环,以便此未提交的警报不会伪装其他警报。轮询循环以一秒间隔开始,并以指数方式后退至30秒间隔。
我正确地理解,在这里说当在服务器上调用WAITANY时,线程会以特定间隔查询事件的存在吗?如果我用足够长的超时调用WAITANY,当事件发生时,我会在当前请求间隔到期后才会收到通知吗?那些。在服务器上就像这个代码
function WaitAny(ATimeout) {
const intervals = [0, 1, ....., 30);
for (i = 0; i < intervals.length; i++) {
Sleep(min(intervals[i], ATimeout))
if (IsExistsEvents())
return 0;
ATimeout -= intervals[i];
if (ATimeout <= 0)
return 1;
}
maxInterval = intervals[intervals.length - 1];
while (ATimeout > 0) {
Sleep(min(maxInterval, ATimeout))
if (IsExistsEvents())
return 0;
ATimeout -= maxInterval;
}
return 1;
}
答案 0 :(得分:1)
不,它仍然是“立竿见影”。
当某人发出警报信号时,它会弹出一个服务员将看到的管道消息(非事务性消息)。但当然,在信号员提交之前,服务员还没有“正式”收到警报。
所以服务员得到了blip,然后等待锁定(使用Oracle的标准锁定机制实现警报)。因为我们期待提交快速到来。
如果没有,那就是一个问题,因为如果我们从不同的警报中获取信号(因为我们在这里做了WAITANY)会怎样。因此,当提交没有到来时,我们将默认并执行指数退避。但它不是“在1,2,4等秒检查警报”,它是“每1,2,4,......秒重新进入等待锁定状态”。所以当这个提交到来时,我们几乎可以直接看到它。
例如,我跟踪了一个2分钟的等待,发出了一个发出警告但未提交
的人的警报declare
n varchar2(100);
m varchar2(100);
s int;
begin
dbms_alert.WAITANY(n,m,s);
end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 127.49 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 127.50 0 0 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 107
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
enq: UL - contention 9 32.01 127.47
log file sync 1 0.00 0.00
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
********************************************************************************
你可以看到2分钟的等待几乎都在等待锁定。