【问题标题】:Can I have a mutex table in my database (Oracle) with just plain SQL?我可以在我的数据库 (Oracle) 中使用纯 SQL 来创建一个互斥表吗?
【发布时间】:2010-08-23 19:00:55
【问题描述】:

我想在我的 Oracle 数据库中有一个表,它的行充当锁。该表将有一个列,一个 varchar,并且我的客户端(通过 JDBC 的 Java 进程)将运行语句来获取和释放锁。

acquire 语句应检查具有给定值的行是否存在,如果不存在则插入。该语句应该以某种方式向调用者发出该行是否空闲的信号。

release 语句应该通过删除行来释放锁。

release 声明很简单,但我的 acquire 声明应该是什么样的?

【问题讨论】:

  • 您为什么要这样做?这听起来像是在重新发明轮子,您还可以应用常规的悲观或乐观锁定。

标签: java sql oracle jdbc


【解决方案1】:

我建议您为此使用DBMS_LOCK。在引擎盖下,它几乎可以满足您的建议。

DBMS_LOCK package

【讨论】:

  • 投了赞成票。 DBMS_LOCK 是一个更安全的选择。使用单行手动操作很容易,直到变得困难 - 如果客户端在删除行之前失去连接会发生什么?是否有任何潜在的路径可以让未捕获的异常绕过发布?如果两个进程都进行测试以检查锁,发现不存在锁,然后继续创建锁,会发生什么情况(我在现实生活中看到过这种情况 - 每隔几天就会发生百万分之一的情况,如果每天有数万笔交易)。
  • “如果两个进程都进行测试以检查锁,发现不存在锁,然后继续创建锁,会发生什么情况”。你不是这样写的。相反,如果你不能,你会尝试创建锁并捕获异常。
【解决方案2】:

您可以在 lockname 上定义一个主键唯一索引。客户会尝试:

INSERT  Locks
        (lockname)
VALUES  'MyLock'

如果这会产生主键冲突,则客户端没有成功获取锁。

【讨论】:

  • 这里的一个弱点是,如果清理的内容(发布声明)由于某些错误而从未运行,会发生什么情况?然后您必须手动删除锁定条目。因此,您需要为此提供某种清理或超时解决方案。
猜你喜欢
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2015-08-09
  • 2012-11-10
相关资源
最近更新 更多