1

假设我有 2 台服务器与同一个事务数据库通信。

我想将其设置为只有这两个服务器中的一个将执行给定的定时操作(本质上是使用数据库来强制同步)。据我所知,类似这样的事情可能会奏效:

假设我的表 TABLE 有 2 列,ID 和 STATUS。如果我这样设置代码:

update TABLE set STATUS = 'processing' where ID = 1234 and STATUS != 'processing'

if (weHaveModifiedAtLeastOneRow)
{
    // do critical section stuff here
    // This is code that we only want one server to run, not both.

    update TABLE set STATUS = 'free' where ID = 1234
}
else
{
    // We failed to get the lock, so do nothing
}

这会起作用吗,还是我在这里遗漏了一些概念?

4

1 回答 1

2

如果您想要一个临界区,请使用dbms_lock.request。您可以像这样通过 allocate unique 获得一个有意义的锁句柄:

DBMS_LOCK.ALLOCATE_UNIQUE ( lockname =>  'MYAPP_' || ID, lockhandle => handle);
success := DBMS_LOCK.REQUEST(lockhandle => handle, timeout => 1);
if (success = 0) then
-- Do stuff
DBMS_LOCK.release(handle);
else
-- we waited a second and didn't got the lock.
end if;

如果您愿意,您可以在 id 上应用哈希和模运算符,将 id 值空间投影到已知数量的锁上,接受延迟不相关事务的(低)风险。

于 2011-07-01T20:41:18.013 回答