【问题标题】:Can Oracle database transactions help in this scenario?Oracle 数据库事务可以在这种情况下提供帮助吗?
【发布时间】:2014-09-22 03:21:28
【问题描述】:

我正在使用 Oracle 数据库(11g 第 2 版)。想象一下多个连接同时执行以下操作:

  1. 开始交易
  2. 检查特定值是否存在于唯一值表中
  3. 如果该值不存在,则插入它
  4. 提交事务

在我看来,防止冲突的唯一方法是阻止连接执行上述 4 步序列,而任何其他连接当前正在执行 4 步序列。

事务可以在 Oracle 中实现这种广泛的锁定/阻塞吗?

提前感谢您就如何最好地处理这种情况提供答案和建议。

【问题讨论】:

    标签: oracle transactions oracle11g database-concurrency


    【解决方案1】:

    添加唯一检查约束,并实现异常处理程序以获取下一个序列并重试。

    这是假设您使用的是 pl/sql。

    另一种方法是使用缓存大小为 1 的 Oracle 序列。这也将确保序列中没有间隙 2. SELECT * FROM table_name FOR UPDATE 阻止所有来自其他会话的读取...

    【讨论】:

    • 啊,是的,唯一的检查约束——防止重复但不会防止不可避免的异常(顺便说一句,这些值是客户端出现的文本字符串,因此序列在这里不起作用)。我希望完全避免例外;如果 Oracle 可以使用读阻塞选项序列化我的事务,那不是很好。
    • 然后你可以在你的选择语句中尝试'for update'。您可以通过省略 where 子句来锁定整个表,或者通过在 where 子句中指定行来锁定特定行
    • 嗯,'for update' 看起来很有希望,但它也不会阻止读取。换句话说,它仍然不会阻止我的应用程序执行第 2 步。似乎没有什么会阻止 Oracle 中的读者。可能只需要在客户端捕获异常。没什么大不了的,只是没有我想要的那么整洁。
    • 我建议你看看这里:docs.oracle.com/cd/E17952_01/refman-5.0-en/select.html,你有 2 种锁定模式。在允许其他会话读取过多的共享模式下,或者在没有共享模式的情况下使用更新,这会阻止从其他会话中选择所选行。如果要阻止所有其他人从表中读取,请使用不带 where 子句的 for update。
    • 感谢您的努力——谢谢。上面的链接实际上是 MySQL 文档,但我找到了 Oracle Database 等价物。我会做一些测试,看看效果如何。将在一两天内更新您并标记您的答案是否正确:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2020-04-18
    • 2020-03-02
    • 2023-04-08
    相关资源
    最近更新 更多