SQL Server NonClustered DeadLock

Question:

Can anybody help me for a deadlock in SQL Server 2005?

For a simple test, I have a table "Book" which has a primary key (id), and a column name. The default index of this primary key is nonclustered.

The deadlock happens when two sessions run at a same time. Activity monitor shows the first session "//step 1" locks the row(rid lock) with X lock. The second session keeps row U lock and key U lock. The deadlock picture shows "//step2" of first session requires key U lock.

If the index is clustered, there is no deadlock in this case. "//step 1" will keep the row and key lock at same time, so there is no problem. I can understand locking a row will also lock the index since leaf node of clustered index is row data.

But, why nonclustered index is in this way? If the second session holds the key U lock, why "step 1" of first session does not hold this lock since they are same the update statement.

--// first session
BEGIN TRAN
  update Book set name = name where id = 1 //step 1
  WaitFor Delay '00:00:20'
  update Book set name = 'trans' where id = 1 //step2
COMMIT

--// second session
BEGIN TRAN
--// this statement will keep both RID(U lock) and KEY(U lock) if first session did not use HOLDLOCK
  update Book set name = name where id = 1
COMMIT
Answer:

The relevant factor here is that you're using a column in your where clause that has a nonclustered index. When SQL Server processes an update, it goes something like this:

  1. Find rows to update, taking U locks on touched data
  2. Update rows, taking X locks on modified data

After the statement completes (under the default READ COMMITTED isolation), the U locks are released but the X locks are held until the end of the transaction to maintain isolation.

In your nonclustered index situation, SQL Server seeks on the index on id and uses this to look up the actual row. The locking plays out like this:

  1. (Session 1, step 1) U lock taken on index key value for id = 1
  2. (Session 1, step 1) X lock taken on RID for row with id = 1
  3. (Session 1, step 1) U lock released
  4. (Session 2) U lock taken on index key value for id = 1
  5. (Session 2) X lock blocked for RID for row with id = 1
  6. (Session 1, step 2) U lock blocked on index key value for id = 1 -- DEADLOCK

However, when the index is the clustered index, there isn't a separate step for converting the index key into the row -- the clustered index value is the row identifier. Therefore, the locking ends up like this:

  1. (Session 1, step 1) U lock taken on index key value for id = 1
  2. (Session 1, step 1) U lock upgraded to X lock
  3. (Session 2) U lock blocked on index key value for id = 1
  4. (Session 1, step 2) lock already held on index key value for id = 1
  5. (Session 1, commit) lock released
  6. (Session 2) U lock granted
  7. (Session 2) U lock upgraded to X lock
  8. (Session 2) lock released

As always, keep in mind that while this may be the query plan used in this case, the optimizer is free to do things differently. For example, it may choose a table scan or to take out more coarsely-grained locks. In these cases the deadlock may not happen.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQLSQL Server是两种不同的关系型数据库管理系统。它们的语句有一些区别,主要包括以下几点: 1. 数据类型:MySQLSQL Server支持的数据类型有所不同,例如MySQL支持的数据类型包括TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT等,而SQL Server支持的数据类型包括TINYINT、SMALLINT、INT、BIGINT、FLOAT、REAL、NUMERIC、DECIMAL等。 2. 语法:MySQLSQL Server的语法也有所不同,例如MySQL使用LIMIT语句来限制查询结果的数量,而SQL Server使用TOP语句来实现同样的功能。 3. 存储过程:MySQLSQL Server的存储过程语法也有所不同,例如MySQL使用DELIMITER语句来定义存储过程的结束符,而SQL Server使用GO语句来分隔多个语句。 4. 索引:MySQLSQL Server的索引语法也有所不同,例如MySQL支持FULLTEXT索引,而SQL Server则支持CLUSTERED和NONCLUSTERED索引。 总之,MySQLSQL Server虽然都是关系型数据库管理系统,但它们的语句有一些区别,需要根据具体情况进行选择和使用。 ### 回答2: MySQLSQL Server是两种常见的关系型数据库管理系统。虽然它们都使用结构化查询语言(SQL)作为操作语言,但实际上存在一些区别。 1.数据类型 MySQL支持的数据类型包括整数(INT和BIGINT),字符(VARCHAR和TEXT)和日期时间(DATETIME和TIMESTAMP)等。而SQL Server还支持二进制大对象(BLOB)、XML、空间和地理位置数据类型等。SQL Server的数据类型比MySQL更多,更加丰富、多样。 2.表和索引 MySQL默认使用的存储引擎是MyISAM,SQL Server默认使用的存储引擎是B-tree。MySQL中创建表和索引时,可以指定不同的存储引擎,而SQL Server只有一种默认的B-tree存储引擎。 3.编程语言 MySQL是用C和C++编写的。使用MySQL的话,可以使用C、C++、PHP、Java、Python等编程语言来操作数据库。而SQL Server一般结合使用MS SQL和Microsoft Visual Studio等编程工具,使用.NET框架来与数据库进行交互。因此,对于不同的编程语言,其操作MySQLSQL Server的语法会有一定的差别。 4.性能和扩展性 MySQL适合处理大量的并发查询,但对于大量并发插入、更新和删除的操作支持相对较弱。而SQL Server则适用于复杂的联合查询和深度数据分析,其对于大量并发插入、更新和删除的操作支持更加完善。当然,这也取决于所应用的硬件环境和应用场景。 总之,MySQLSQL Server是两种不同的数据库管理系统,而在操作语言使用上,它们还是存在一些区别的。但无论是哪种数据库管理系统,应用场景的不同也会影响到其使用差异,应根据实际需求来选择合适的数据库管理系统。 ### 回答3: MySQLSQL Server都是常用的关系型数据库管理系统,都支持SQL语言作为操作数据库的主要语言。但是,两者在SQL语言的标准化实现和特有拓展方面存在差异,导致了一些语句的在两者之间的不兼容。 1. 数据类型 MySQLSQL Server在数据类型的定义方面存在差异。例如:MySQL中的auto_increment可以设置为BIGINT类型,而在SQL Server中只支持INT类型;又如:MySQL中的ENUM类型可以存储枚举值,而SQL Server中没有类似的数据类型。 2. 函数 在函数方面,MySQLSQL Server都有很多自己的函数,但是有些函数名在两者之间存在差别。例如:MySQL中的DATE_FORMAT函数用于将日期格式化,而SQL Server中的DATENAME则返回日期的名称。 3. 子查询 MySQLSQL Server对子查询的支持也有所不同。MySQL允许在select、from、where子句中任何位置使用子查询,并且认为子查询中的表是对外不可见的;而SQL Server只允许在from和where子句中使用子查询,并把子查询中的表看作一个临时表。 4. 字符串拼接 字符串拼接在开发中是常用的操作之一,但是在MySQLSQL Server中实现方式不一。MySQL使用concat函数完成字符串拼接,SQL Server使用+号来拼接字符串。 5. 索引 在索引的创建方面,MySQLSQL Server也存在差异。MySQL中可以为一个列创建多个索引,而SQL Server的一个列只能创建一个索引。此外,SQL Server中可以为一个视图创建索引,而MySQL中则不能。 总的来说,MySQLSQL Server在语句的实现和特有扩展上存在差异,开发者在操作时应该注意到这些差别,在实际开发中要结合实际情况选择适合的数据库,并根据不同的场景选择相应的操作语句。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值