Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何配置MS SQL server以避免更新锁定(LCK_M_)_Sql Server_Transactions - Fatal编程技术网

Sql server 如何配置MS SQL server以避免更新锁定(LCK_M_)

Sql server 如何配置MS SQL server以避免更新锁定(LCK_M_),sql-server,transactions,Sql Server,Transactions,我有一个MS SQL server数据库,其中包含多个表。每个表都有一个字段“SN”。多个客户端可以使用此数据库,但每个客户端仅使用具有其自身SN值的记录进行操作 一种类型的客户端应用程序是使用pyodbc用python编写的遗留软件。据我所知,该软件可以创建长事务—它可以执行UPDATE或INSERT语句,并在几个小时后提交它们。我知道,这样做是错误的,但修改那个软件是不可取的 事务隔离级别设置为READ_COMMITTED,READ_COMMITTED_SNAPSHOT设置为ON 除以下情况

我有一个MS SQL server数据库,其中包含多个表。每个表都有一个字段“SN”。多个客户端可以使用此数据库,但每个客户端仅使用具有其自身SN值的记录进行操作

一种类型的客户端应用程序是使用pyodbc用python编写的遗留软件。据我所知,该软件可以创建长事务—它可以执行UPDATE或INSERT语句,并在几个小时后提交它们。我知道,这样做是错误的,但修改那个软件是不可取的

事务隔离级别设置为READ_COMMITTED,READ_COMMITTED_SNAPSHOT设置为ON

除以下情况外,一切正常:

  • 首先,legacy clent启动事务,该事务使用其SN值(例如SN=1)更新记录
  • 另一个客户端应用程序尝试使用其SN值更新记录,例如SN=2
  • 这种情况会导致第二个客户端的LCK_M_锁定: ridlock field=1 pageid=311 dbid=5 id=lock2776cf380 mode=X associatedObjectId=…此处有许多数字

    尽管这两个客户端使用不同的SN值,但这会导致锁定。我怀疑这是因为SQLServer锁定的不是特定的行,而是页面(我猜是行的集合)

    根据SO question(),由于锁升级,无法保证行锁

    我考虑过将事务隔离级别设置为“readuncommitted”,但我不确定这是否正确


    是否有任何方法可以正确配置MS SQL server以解决此锁定并允许“同时”更新不同的行?

    SN
    上分区可能是最好的方法。您可以使用另一种方法,但请谨慎使用。您可以通过启用跟踪标志1211来禁用锁升级。但是,此跟踪标志全局禁用SQL Server实例中的所有锁升级。锁升级在SQL Server中有一个非常有用的用途,它可以最大限度地提高查询的效率,否则查询的效率会因获取和释放数千个锁的开销而降低。锁升级还有助于最小化跟踪锁所需的内存。SQL Server可以为锁结构动态分配的内存是有限的,因此如果禁用锁升级,并且锁内存足够大,则尝试为任何查询分配额外的锁可能会失败。

    我找到了一个对我来说似乎可行的解决方案。如中所述。其思想是为表中的SN字段创建索引,如下所示:

    CREATE INDEX IX_SN ON TABLE_NAME(SN)
    

    您可以基于SN对表进行分区。这将删除多个客户端之间的锁定冲突。不确定这样做是否好。大多数表只包含一条具有特定SN的记录(它可以像主键一样在整个表中是唯一的),并且可以有大量不同的SN。另外,分区的数量也有限制。谢谢你的建议。关于分区-请参阅我在原始问题下面的第一条评论。禁用锁升级不是一种可行的方法,因为服务器实例还为另一个数据库提供服务,这样的更改可能是不需要的。