sql-server - MS Access 直通选择查询导致 SQL Server 中的页面锁定

标签 sql-server ms-access sql-server-2008-r2 locking

我正在使用链接到 SQL Server 2008 R2 后端的 Access 2007 前端,并且遇到了我认为是由简单的直通选择查询引起的奇怪锁定行为。更具体地说:

我有一个简单形式的直通查询“SELECT * FROM tbl_A”。如果我在 access 中打开此查询(普通数据表查询 View )并且该表有足够多的记录(大约 > 100 条记录,我还没有尝试找到精确的界限),那么我会在 SQL Server 中获得对该表的锁定只要我保持查询打开。如果我尝试在表上运行更新查询或类似的查询,则会导致死锁。如果我打开一个连续表单,并将此直通查询设置为记录源,也会发生同样的情况。查看 SQL Server 中的 sys.dm_tran_locks View 显示它是数据页上的 IS 锁...不知道这是否有帮助。一旦我单击 Access 中的“最后一条记录”按钮滚动到查询或表单的末尾,锁定就会被清除,我的其他进程可以再次更新表。

据我所知,我的表单和/或查询属性已设置为其默认值(记录集类型=动态集,记录锁定=无锁)。基于动态集的描述,例如此处给出:https://msdn.microsoft.com/en-us/library/bb188204.aspx 我希望它只加载填充可视区域所需的小批量数据,而不会长时间锁定服务器。正如链接文章所述:

Because they work with only a few rows at a time, dynasets minimize the duration that read locks are held on the server. This allows other users to modify data without having to wait as long as is necessary for locks to clear.

任何人都可以解释为什么动态集没有按预期运行吗?

我已经看到了建议的几种可能的解决方法,例如

  • 使用 NOLOCK 提示(如此处建议 MS Access holds locks on table rows indefinitely ,但似乎一般不鼓励使用 NOLOCK?)
  • 使用断开连接的 ADO 记录集作为表单的记录源
  • 将数据从服务器拉入客户端的临时表,并基于这些临时表构建表单
  • 重新设计前端,添加限制器等,以便表单永远不会拉取超过 100 条记录(这将是大量工作,而且如果不能保证永远不会锁定指定数量的记录,则似乎不安全)

所有这些建议要么对我不起作用,要么似乎有许多其他缺点和/或需要对前端进行重大重写...解决这个问题的最佳方法是什么?

最佳答案

经过进一步挖掘和实验,我看到的是这样的:

使用 SQL Server 上的默认设置,Access 的动态集会保持读锁定,直到完全加载所有数据为止。这对于避免不一致的读取是必要的,否则其他事务可能会进入并更改正在拉取的动态集的后续“数据包”之间的数据顺序,这可能会导致重复的行被拉取或行被丢失。 (如果在查询运行时重建 SQL Server 页面,则与 NOLOCK 查询可能发生的情况类似)。

所以似乎只有两种方法可以避免它:

1) 强制 Access “完成”查询,方法是使用快照而不是动态集,或者对动态集执行某种“最后移动”操作,或者确保 select 语句仅返回很少的记录Access 将立即加载它们。

2) 使用 NOLOCK 提示或在 SQL Server 数据库中设置 READ_COMMITTED_SNAPSHOT ON 来防止读锁定。

我们将使用 READ_COMMITTED_SNAPSHOT ON 选项,因为这意味着前端不需要进行任何更改,而且无论如何,我通常不喜欢在执行读取操作时阻止写入操作。

关于sql-server - MS Access 直通选择查询导致 SQL Server 中的页面锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42382578/

相关文章:

javascript - 当值低于前一个值时,有没有办法在 Highcharts 中动态创建情节线?

sql-server - SQL Server 2017 AG 上启用 DTC 的 tSQLt

c# - 像在 SQL 中一样在 C# 中比较字符串

sql - 如何确定更新触发器中更新了哪些字段

c# - 如何在EF中获取外键上最大联系人数的对象

ms-access - 在 Access VBA 中禁止写入冲突消息

sql-server - 从 MS Access 中的表自动更新 SQL Server 数据库

ms-access - Access VBA : Find item in combo box based on non-bound column

SQL Server 2008 R2 内连接无法匹配 varchar 字段,因为它包含特殊字符

sql - 更新语句与 ASP.NET MVC4 中的 FOREIGN KEY 约束冲突