【问题标题】:Select unlocked rows oracle选择未锁定的行 oracle
【发布时间】:2012-12-16 07:55:02
【问题描述】:

我有一个使用 Oracle 数据库的 C# 应用程序。 我需要一个查询来从 oracle 数据库中的表中获取未锁定的行。 如何选择所有未锁定的行?

是否有任何“翻译器”可以将此 T-SQL (MS SQL Server) 查询翻译成 Oracle 方言?

SELECT TOP 1 * FROM TableXY WITH(UPDLOCK, READPAST);

我对 Oracle 缺少这样的功能有点失望。他们想让我使用 AQ 还是什么?

【问题讨论】:

  • Oracle 和 MS SQL Server 以非常不同的方式处理锁定。在 Oracle 中没有锁管理器,锁不会级联,写入器不会阻塞读取器,反之亦然。在编写查询(例如上面的示例)时,您可以有效地忽略锁定注意事项,并且您的结果将在查询执行时保持一致。

标签: c# database oracle oracle11g


【解决方案1】:

Oracle 确实具有此功能,特别是 SELECT statement 的 SKIP LOCKED 部分。引用:

SKIP LOCKED 是处理竞争事务的另一种方法 那是锁定一些感兴趣的行。指定 SKIP LOCKED 指示 数据库尝试锁定 WHERE 子句指定的行 并跳过发现已被另一行锁定的任何行 交易。

文档继续说它是为在多消费者队列中使用而设计的,但这并不意味着您必须在这种环境中使用它。尽管文档说这是有一个很大的警告。您不能要求接下来的 N 行解锁 - 只有接下来的 N 行,其中解锁的行将被返回。

SELECT * 
  FROM TableXY 
 WHERE ROWNUM = 1
   FOR UPDATE SKIP LOCKED

请注意,如果您选择的表被锁定为独占模式,即您已经指示数据库不要让任何其他会话锁定该表,您将不会返回任何行直到排他锁被释放。

【讨论】:

  • 请:是否有锁定的行用于读取当前在 oracle 中更新的行
  • 对不起@hussein_moh,我不明白你在说什么。这实际上等同于发布的 T-SQL 代码。它获取当前未锁定的第一行并将其锁定。您可以选择锁定的行,但您将无法对它们执行任何操作。您是否试图锁定当前的每一行?
  • @hussein_moh:在 Oracle 中,你不能锁定一行被选中。
  • 嗨! Ben 你的帖子解决了我的问题,但我还需要 Lock 阅读器来防止选择当前正在更新的记录
  • 嗨@a_horse_with_no_name 为什么?在 Oracle 中,您不能锁定一行不被选中!我该怎么做?
【解决方案2】:

我最近遇到了同样的问题,解决后写了这篇博文:

http://nhisawesome.blogspot.com/2013/01/how-to-lock-first-unlocked-row-in-table.html

随时发表评论!感谢您的 cmets。

简短的总结:我没有选择第一个解锁的记录并锁定它,而是选择了一堆记录,然后循环遍历这些记录并尝试使用 SKIP LOCKED 提示获取对它的锁定。如果选定的一个不可锁定,则继续执行下一个,直到获得锁定或没有剩余。

【讨论】:

    【解决方案3】:

    如果您选择锁定的行,select for update nowait 将出错。那是你要的吗?我很好奇您要解决什么问题。除非您有长时间运行的事务,否则行上的锁定会从一个时刻到下一个时刻是短暂的。

    例子:

    创建表测试 ( COL1 编号(10)不为空, COL2 VARCHAR2(20 字节) 非空 );

    在测试时创建唯一索引 TEST_PK (COL1);

    更改表测试添加 ( 约束测试_PK 首要的关键 (COL1) 使用索引测试_PK );

    SQL 会话 #1: SQL> 插入测试值(1,'1111'); 创建了 1 行。 SQL> 插入测试值(2,'2222'); 创建了 1 行。 SQL>提交; 提交完成。 SQL> 更新测试集 col2='AAAA' where col1=1; 更新了 1 行。

    SQL 会话 #2:尝试读取锁定的行,得到错误:

    SQL> select * from test where col1=1 for update nowait; select * from test where col1=1 for update nowait * 第 1 行的错误: ORA-00054: 资源繁忙并使用指定的 NOWAIT 获取或超时已过期

    【讨论】:

    • 我想阻止其他用户读取另一个用户当前正在更新的记录
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    相关资源
    最近更新 更多