【问题标题】:Firebird lock and select unlocked fieldsFirebird 锁定并选择未锁定的字段
【发布时间】:2018-02-10 15:15:30
【问题描述】:

我有一个问题

SELECT FIRST 10 * FROM FP_TASKS WITH LOCK

但是我有多个客户端使用一个表,我需要为每个选定的客户端设置 10 行未锁定的行。 有什么办法可以做下面这样的事情吗?

SELECT FIRST 10 * FROM FP_TASKS
 WHERE ROW NOT LOCKED
WITH LOCK

【问题讨论】:

  • SELECT FIRST 10 * FROM FP_TASKS - 这意味着“随机选择 10 行” - 因为您没有指定任何顺序
  • Firebird 是多版本服务器,锁定对它来说是不自然的。我想,你最好重新考虑一下你的应用程序的操作模式。如果您真的需要它,您可以在表中添加列,锁定该行的连接 ID。对于 IB/FB 来说,这似乎仍然是相当不自然的工作流程
  • 我相信最好的方法是识别连接,正如你所说。我的应用程序有一个使用该表的子进程,我们连接的客户端可以在其中相互分配工作负载,因此客户端可以选择任何行以任何特定顺序进行处理。谢谢!
  • 然后还可以查看数据库级触发器,如果​​您的客户端或其连接崩溃,那么服务器应该释放该连接的锁定
  • 我在“断开连接”事件上添加了一个触发器,并且效果很好:) ty

标签: sql firebird deadlock database-deadlocks


【解决方案1】:

如果您在一行中持有一个锁,那么另一个事务中的另一个select .. with lock 将等待锁被释放或引发异常(取决于事务配置)。

选择时无法忽略或跳过锁定的行。 Firebird documentation 还明确表示:

WITH LOCK 提供有限的显式悲观锁定功能 在受影响的行集为以下情况时谨慎使用:

一个。非常小(理想情况下是单例),并且
湾。由应用程序代码精确控制。

您的查询既不是“非常小”,也不是由您的应用程序“精确控制”。

您应该考虑使用短事务来分配行,该事务使用某种类型的连接特定声明更新行,或者可能是单个生产者或资源管理器将行分配给特定客户端。

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2014-05-14
    • 2018-11-09
    相关资源
    最近更新 更多