Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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 如果我';我没有在事务中执行查询吗?_Sql Server_Transactions_Deadlock - Fatal编程技术网

Sql server 如果我';我没有在事务中执行查询吗?

Sql server 如果我';我没有在事务中执行查询吗?,sql-server,transactions,deadlock,Sql Server,Transactions,Deadlock,假设我打开一个事务并运行更新查询 BEGIN TRANSACTION UPDATE x SET y = z WHERE w = v 查询成功返回,事务在我决定提交之前故意保持打开状态一段时间 当我坐在事务上时,MSSQL死锁机制是否有可能在达到系统内存/资源限制时抢占我实际未执行任何操作以清除死锁或释放资源的打开的事务 我知道设置死锁的优先级,并阅读了MSDN关于死锁的文章。从逻辑上讲,由于我并没有积极寻求对任何额外资源的权利主张,所以我无法想象会触发一个合理的死锁避免算法的场景 有没有人确切

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

BEGIN TRANSACTION
UPDATE x SET y = z WHERE w = v
查询成功返回,事务在我决定提交之前故意保持打开状态一段时间

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

我知道设置死锁的优先级,并阅读了MSDN关于死锁的文章。从逻辑上讲,由于我并没有积极寻求对任何额外资源的权利主张,所以我无法想象会触发一个合理的死锁避免算法的场景


有没有人确切地知道,仅仅持有任何锁就可以使我成为一个有效的目标?类似地,任何低资源条件是否会触发我的SPID被终止?

仅仅因为您不在事务中并不意味着您没有持有锁。

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

至于其他可能导致会话失败的情况,我至少可以想到三个:

  • 与回滚\u IMMEDIATE一起使用的管理操作
  • 镜像故障切换
  • 故意的
    杀戮
    ,可能是友好的DBA开的玩笑

    • 交易可能会超时,这就是正在发生的情况

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


      一些系统在分离死锁类型的问题时,只是开始终止“长寿命”事务,这些事务并没有完成匹配工作,以便释放锁。仅仅因为您不是死锁循环的一部分,并不能阻止系统攻击您

      要了解案例中发生的情况,您必须使用Sql Server Profiler收集所有与锁定和死锁相关的事件,以及有关中止连接和事务等的事件。这将花费一些时间,并且对您正在查看的探查器事件有很好的理解

      这类事情的细节在数据库供应商及其数据库版本之间是不同的。但是,由于大多数数据库供应商认为事务长时间打开是一种糟糕的设计,因此这样做往往会导致问题,并导致没有进行最多测试的代码路径。

      可能的问题:

    • SQL Server只有有限数量的锁。锁可能用完了

    • 其他资源是有限的(例如内存、tempdb)。保留这些资源可能会导致资源耗尽

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

    • 考虑:

    • CASCADE:DELETE命令中可能只有一个表,但是CASCADE关系可能会接触其他表

    • 触发器:修改表上的触发器可能会影响其他表

    • DELETE和UPDATE命令可以使用FROM子句,该子句与其他表相接触。我从未见过这种情况,但我不排除这种可能性


    • 回答您的问题:如果您没有在事务中执行查询,您可能成为死锁受害者

      这与直觉相反,但通过运行
      SELECT
      语句,您可以成为死锁受害者

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

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

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

      • 您现在希望从匹配行的数据页中提取数据

        在数据页上保持锁定的其他进程

        等待数据页锁释放

      • 其他进程已完成数据页更新,希望更新索引

        您在索引上持有读锁

        其他进程等待释放索引锁

      • 死锁

      因此,严格来说,当您不在事务中执行查询时,可能成为死锁受害者。另一个人也没有在事务中执行他的
      UPDATE
      语句


      没有人明确使用事务,但却出现了死锁。

      我不确定(这就是为什么这是一条评论),但我认为,如果您只是在打开锁的情况下闲逛,您更有可能被选为死锁受害者(而不是不太可能)。死锁发生在两个进程需要相同的资源,并且两个进程都不会放弃时。如果您持有锁,那么您就更有可能(而不是更少)使流程陷入死锁。至于哪一个spid是受害者,我从未听说它的选择过程在用户级别是确定的。不管是哪种方式,你持有锁的时间越长,你的胜算就越大。我明白你为什么贴这篇文章了,标题写得很糟糕。但是,他的意思是,在事务中,他实际上并没有运行查询。(他在交易中,但没有做SQL之类的事情。)至少我是这么看的。正如我所说,重要的不是他是否在交易中——重要的是loc