2011-06-07 22 views
1

我遇到了使用Sync Framework进行自定义冲突处理的一个非常奇怪的问题。考虑到以下简单的数据库结构:同步框架 - FK列中的更新/更新冲突导致FK表中的锁定

CREATE TABLE [dbo].[Container](
    [Id] [uniqueidentifier] NOT NULL DEFAULT newid(), 
    [LocationId] [uniqueidentifier] NULL REFERENCES [dbo].[Location], 
    ..... 
) 

CREATE TABLE [dbo].[Location](
    [Id] [uniqueidentifier] NOT NULL DEFAULT newid(), 
    [Name] [varchar](100) NULL, 
    ..... 
) 

现在假设我在我的数据库中有一个容器。在客户端上,我将其LocationId设置为一个值。在服务器上,我将它设置为其他值。我尝试进行同步,并且如所期望的那样,我收到LocalUpdateRemoteUpdate类型的ApplyChangeFailedEvent。

作为我的冲突解决过程的一部分,我想向用户显示有关冲突的信息,并让他们选择正确的位置。为此,我需要在客户端和服务器端读取与LocationId对应的位置,这就是问题出现的地方。我的读取超时,因为同步框架似乎锁定了表。 sp_lock2显示位置表上有一个'X'类型的锁。

The kicker是,这只发生在一些外键列一些表。他们大多数都很好,但其中一些人每次都会造成排他性锁定。

如果有人对冲突解决期间具体造成排他锁的具体情况有所了解,或者我可以采取什么措施来避免它或解决它,将不胜感激。如果我在冲突解决期间无法可靠地读取数据库,那么我的整个冲突处理策略几乎毫无意义。

更新: 看起来我有点不对。它不锁定整个表格,只锁定冲突中涉及的记录。我可以做一个SELECT * FROM位置WHERE ID =(没有参与冲突的记录的ID),我只是不能做一个SELECT * FROM位置WHERE ID =(冲突记录的ID)。

+0

你是否在同步多行?可能是你正在更新许多行,Sql Server决定将它升级到表级锁? afaik,Sync Fx确实注意到了明确的锁问题,并依靠Sql Server来完成。 – JuneT 2011-06-08 10:17:58

+0

感谢您的回复。这似乎是有道理的,尽管在这种情况下它甚至发生在单行中。 – 2011-06-09 21:56:06

+0

您是否在与容器相同的范围内同步位置?你在哪个表中得到冲突?在引用Location表的同步作用域中是否有其他表? – JuneT 2011-06-20 07:58:27

回答

1

我不完全确定为什么,但我可以通过在READ UNCOMMITTED事务中执行读取操作来解决问题。去搞清楚。

+0

您可以阅读它,因为您明确忽略了该行的事务状态。如果该行刚刚更新并且尚未提交,则您正在读取未提交的值。取决于你在做什么,这可能会导致你在其他地方使用未提交值并且原始事务回滚的问题。 – JuneT 2011-06-20 08:01:04

+0

谢谢!这正是我所需要的。我只想读取本地关系行以向用户显示差异。花了我几个小时才找到这个答案。 – Pepedou 2017-09-04 20:20:07