如果我没有在事务中执行查询,我可以成为死锁受害者吗?

时间:2010-01-13 07:26:20

标签: sql-server transactions deadlock

假设我打开一个事务并运行更新查询。

BEGIN TRANSACTION
UPDATE x SET y = z WHERE w = v

在我决定提交之前,查询成功返回并且事务在一段时间内保持打开状态。

当我坐在事务上时,MSSQL死锁机器人是否有可能抢占我实际上没有执行任何操作的开放事务,以便在达到系统内存/资源限制时清除死锁或释放资源?

我知道SET DEADLOCK_PRIORITY并阅读了有关死锁主题的MSDN文章。从逻辑上讲,由于我没有积极寻求对任何额外资源的索赔,我无法想象会触发一个理智的死锁避免算法。

有没有人确定是否可能只是持有任何锁定可以使我成为有效目标?同样,任何低资源条件都会触发我的SPID被杀?

5 个答案:

答案 0 :(得分:3)

要发生死锁,死锁链中的所有参与者必须等待获取资源(锁定)。如果您的连接处于空闲状态,则意味着它不会执行请求,这意味着它无法等待。

至于可以杀死你的会话的其他条件,我至少可以想到三个:

  • 使用WITH ROLLBACK_IMMEDIATE的管理操作
  • 镜像故障转移
  • 故意KILL <yourspid>,也许是你友好的DBA的笑话

答案 1 :(得分:3)

要回答您的问题:如果您未在交易中执行查询,可以成为死锁受害者。

这是违反直觉的,但你可以通过运行SELECT声明成为死锁的受害者。

如果您正在运行使用索引的查询,则会发生这种情况:

  • 您扫描索引以查找匹配的行

  • 其他流程开始更新数据页

  • 您现在想从匹配行的数据页中获取数据

    其他进程持有数据页锁定

    等待数据页锁定释放

  • 其他进程完成更新数据页面,想要更新索引

    您持有索引上的读锁

    其他进程等待索引锁释放

  • <强> DEADLOCK

因此,严格来说,当您未在事务中执行查询时,可以成为死锁受害者。另一个人也没有在交易中执行他的UPDATE陈述。

没有人明确使用交易,但存在僵局。

答案 2 :(得分:0)

交易可能会超时,就是发生了什么。

由于您至少有一个(或多个)更新锁被取出并成为一些读取和表扫描锁,您可能会被杀死以帮助释放由其他事务创建的死锁。 SQL Server中的死锁恢复代码不太可能完全没有bug,并且在SQL Server上长时间保持事务是不正常的。但是我不希望这种情况经常发生。


某些系统在分离死锁类型问题时,只是开始杀死尚未完成匹配工作的“长期存在”事务,以释放锁定。仅仅因为你不是死锁循环的一部分,不会阻止系统选择你。

要了解您的案例中发生了什么,您必须使用 Sql Server Profiler 来收集所有与锁定和死锁相关的事件以及事件关于中止的连接和交易等。好的缺乏这将花费一些时间和对你正在寻找的探查器事件的良好理解......

这类事情的细节在数据库供应商和他们的数据库版本之间是不同的。但是,由于大多数数据库供应商认为长时间打开事务被认为是不好的设计,因此这样做往往会导致问题并导致代码路径没有经过最大的测试工作。

答案 3 :(得分:0)

可能出现的问题:

  1. SQL Server只有有限数量的锁。可能会用完锁。

  2. 其他资源是有限的(例如内存,tempdb)。坚持这些资源可能会导致这些资源耗尽。

  3. 事务日志 - 如果事务处于打开状态,则无法释放逻辑事务日志以供重用。结果可能是填满的日志。此问题可能会停止您的进程,因为它会暂停整个实例。

  4. 考虑:

    1. CASCADE:DELETE命令中只能有一个表,但CASCADE关系可能会触及其他表。

    2. 触发器:修改后的表上的触发器可能会影响其他表。

    3. DELETE和UPDATE命令可以使用与其他表接触的FROM子句。我从来没有见过这个,但我不会排除它。

答案 4 :(得分:-1)

仅仅因为你没有参与交易并不意味着你没有拿着锁。