我有两个长时间运行的查询,都是事务型的,并且访问相同的表,但是在这些表中完全是不同的行。这些查询还根据这些查询执行一些更新和插入操作。
似乎当这些查询同时运行时,它们遇到了某种锁,这会阻止任务完成,并且在执行对其中一个行的更新时锁定。我正在读取被锁定的行时使用排他的行锁定,而显示在进程上的锁是lck_m_ix锁。
两个问题:
- 当我更新/插入单个行时,它是否锁定整个表?
- 可以采取什么措施来解决这类问题?
我有两个长时间运行的查询,都是事务型的,并且访问相同的表,但是在这些表中完全是不同的行。这些查询还根据这些查询执行一些更新和插入操作。
似乎当这些查询同时运行时,它们遇到了某种锁,这会阻止任务完成,并且在执行对其中一个行的更新时锁定。我正在读取被锁定的行时使用排他的行锁定,而显示在进程上的锁是lck_m_ix锁。
两个问题:
简短版:
详细版:
LCK_M_IX是一个意向锁,这意味着该操作将在下属元素上放置一个X锁。例如,在更新表中的某一行时,操作会在锁定正在更新/插入/删除的行之前,对表(table)进行IX锁定。意向锁是处理层次结构(如table/page/row)的常见策略,因为锁管理器无法理解要锁定的资源的物理结构(即它无法知道在页面P1上的X锁与行R1上的S锁不兼容,因为R1包含在P1中)。有关更多详细信息,请参见锁模式。
如果您看到意向锁争用的事实,这意味着您正在尝试获得高级对象锁,例如表格锁。您需要分析被阻止请求的源代码(请求与LCK_M_IX不兼容的锁),并消除对象级别锁请求的原因。具体来说取决于您的源代码,我无法知道您在那里做什么。我猜测您使用了错误的锁提示。
更通用的方法是依赖快照隔离。但是,这很可能无法解决您看到的问题,因为快照隔离只能有益于行级争用问题,而不能解决请求表格锁的应用程序。