简体   繁体   English

可以更新到ParentTable在SQL SERVER 2008中具有外键关系的子表中查找原因

[英]Can update to a ParentTable cause lookup in Child table with foreign Key relationship in SQL SERVER 2008

following tables are part of Database Design. 下表是数据库设计的一部分。 I donot have any Non-Clustered index on my Foreign Keys. 我的外键上没有任何非聚集索引。

在此处输入图片说明

I am locking PatientChartImages table by using the following command 我通过使用以下命令锁定PatientChartImages表

begin transaction t1
update PatientChartImages set RotationAngle = 55
--ROLLBACK TRANSACTION t1

After that, All updates to the User Table are timing out.I am attaching the SqlProfiler trace. 之后,所有对用户表的更新都将超时。我将附加SqlProfiler跟踪。 The selected command in that image is causing TimeOut. 该映像中的所选命令导致超时。 since I am updating PatientChartImages and CreatedByUserId in PatientChartImages is not a FK to main user table, why are Fk lookups causing TimeOut. 由于我正在更新PatientChartImages中的PatientChartImages和CreatedByUserId不是对主用户表的FK,为什么Fk查找会导致超时。

According to Me, the following sequence is happening 据我说,以下顺序正在发生

  1. Transaction has a Exclusive lock on PatientChartImages 交易对PatientChartImages具有排他锁
  2. Since PatientChartid in PatientChartImages is a FK to PatientChartid in PatientCharts, this is causing Foreign Key Lookup and is locking PatientCharts table. 由于PatientChartImages中的PatientChartid是PatientCharts中的PatientChartid的FK,因此这将导致外键查找并锁定PatientCharts表。
  3. Similarly as CreatedByUserId in PatientCharts table is a FK to UserID in Users table,so FK lookups are also locking Users table. 类似于PatientCharts表中的CreatedByUserId是Users表中的FK到UserID,因此FK查找也锁定了Users表。

Is my understanding on this correct? 我对此的理解正确吗? Please suggest and also tell me how can i prevent this kind of locking. 请提出建议,并告诉我如何防止这种锁定。

Trace ScreenShot 跟踪屏幕截图 在此处输入图片说明

I am pretty sure your understanding of the situation is correct. 我很确定您对情况的理解是正确的。

As you obviously know, when performing a SQL transaction, any update which can affect the tables you're updating needs to be prevented. 众所周知,执行SQL事务时,必须防止可能影响要更新的表的任何更新。 Think about the ACID principles (http://en.wikipedia.org/wiki/ACID). 考虑一下ACID原则(http://en.wikipedia.org/wiki/ACID)。

I think the only way round this is to use READ UNCOMMITTED or NOLOCK 我认为唯一的解决方法是使用READ UNCOMMITTEDNOLOCK

Implements dirty read, or isolation level 0 locking, which means that no shared locks are issued and no exclusive locks are honored. 实现脏读或隔离级别0锁定,这意味着不会发出共享锁,也不会使用独占锁。 When this option is set, it is possible to read uncommitted or dirty data; 设置此选项后,可以读取未提交的数据或脏数据。 values in the data can be changed and rows can appear or disappear in the data set before the end of the transaction. 在事务结束之前,可以更改数据中的值,并且行可以在数据集中显示或消失。 This option has the same effect as setting NOLOCK on all tables in all SELECT statements in a transaction. 此选项与在事务中所有SELECT语句的所有表上设置NOLOCK作用相同。 This is the least restrictive of the four isolation levels. 这是四个隔离级别中限制最小的。

You can work out the risks of this for yourself. 您可以自己解决此风险。

I actually think the answer is to keep the transaction as short as possible and put up with it, as it's only doing this to protect data integrity. 我实际上认为答案是使事务尽可能短并忍受,因为这样做只是为了保护数据完整性。 eg only start and end the transaction around the actual update operations. 例如,仅在实际更新操作周围开始和结束事务。

I hope this helps a bit. 我希望这个能有一点帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM