【问题标题】:How to avoid unwanted transactions and locks using FireDAC and SQL Server如何使用 FireDAC 和 SQL Server 避免不需要的事务和锁定
【发布时间】:2020-11-22 10:40:34
【问题描述】:

通过分析 SQL Server 中的表锁,我在 RAD Studio XE7 中构建的 Win32 应用程序在每个 FDQuery 处于活动状态时启动了大量事务。有时这会导致应用程序出现问题并锁定数十个用户。尤其是触发表。

对于我的测试,我使用简单的 FDConnection 和 FDQuery 作为默认设置的Select * from Customer,并得出结论FDQuery1.Active:=True 导致客户表事务的启动。交易在FDQuery1.Active:=false时消失。

我想禁止在 FDQuery 中以只读方式启动事务,作为网格或报告的数据列表。

但我找不到合适的 FDQuery 调优方法。

【问题讨论】:

  • 调整 SQL Server 的设置使读者不会阻止作者是最简单的。它会产生更多的存储负载,但使用行版本控制而不是为读者锁定可以消除很多死锁。阅读 READ_COMMITTED_SNAPSHOT。大多数其他数据库都使用这种方法。
  • 谢谢布赖恩。但是,我不能将属性 TFDConnection.TxOptions.xiShapShot 与您提到的 SQL Server 设置一起考虑,因为数据库太大并且许多用户同时工作。在这种情况下,我想建议调整组件 FDQuery 的属性,以便获得不加锁的查询。
  • 不要将 FireDAC 与 SQL 服务器一起使用。请改用“本机”ADO (dbGO) 组件。我这样做。这只是一个建议。您的里程可能会有所不同。

标签: sql-server delphi firedac


【解决方案1】:

默认情况下,SQL Server 不实现数据块的版本控制。因此,为了返回一组一致的行,它保证没有其他会话在执行查询期间使用共享锁对数据进行更改。

使用“WITH(NOLOCK)”禁用共享锁,但会导致结果集不一致。

唯一的解决方案是使用 READ_COMMITED_SNAPSHOT 隔离级别,它将更改的数据存储到 temp,用于返回一致的结果集而不锁定更新。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 我试过select * from Customers with (NOLOCK)。但是无论如何创建了交易。 FireDAC 之前可能会启动一个隐式事务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 2018-06-14
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 2013-06-07
    相关资源
    最近更新 更多