我有一个夜间作业,它执行一个存储过程,它遍历一个表并获取要插入到另一个表中的记录。
过程持续时间约为4-5分钟,在具有~3M记录的表上执行6个选择。
在运行此过程时,会从试图更新同一表的另一个存储过程抛出异常:
我读过Why use a READ UNCOMMITTED isolation level? 的问题,但没有得出最适合我的方案的结论,正如其中一条评论所述:
作者似乎暗示,读未提交/没有锁将返回上次提交的数据。我的理解是,读未提交将返回上次设置的值,即使是从未提交的事务中返回。如果是这样,结果将不会是检索“几秒钟过期”的数据。它将(或者至少如果写入您读取的数据的事务被回滚)将检索不存在或从未提交的数据“。
考虑到,我只关心夜间作业启动时行的状态(同时,更新将在下一次更新中计算),什么是最合适的方法?
发布于 2018-04-09 10:30:58
事务(进程ID 166)与另一个进程在锁定资源上陷入僵局,并被选择为死锁受害者。重新运行事务。
通常情况下,当您读取数据并打算稍后通过放置共享锁来更新它时,下面的update语句无法获得必要的Update Locks
,因为它们已经被在不同会话中获取的共享锁所阻塞,从而导致死锁。
要解决这个问题,可以使用UPDLOCK
选择记录,如下所示
SELECT * FROM [Your_Table] WITH (UPDLOCK) WHERE A=B
这将预先对记录采取必要的更新锁,并将停止其他会话以获取记录上的任何锁(共享/独占),并防止任何死锁。
死锁(Cycle Deadlock
)的另一个常见原因是您在查询中放置的语句的顺序,最后,每个查询都在不同的事务中等待另一个查询。对于这类场景,您必须访问查询并修复排序问题。
执行超时已过期。在操作完成或服务器没有响应之前经过的超时时间。-> System.ComponentModel.Win32Exception (0x80004005):等待操作超时
这是非常清楚的,您需要处理查询性能,并尽可能少地保持记录锁定。
https://stackoverflow.com/questions/49730675
复制相似问题