Me enfrento a algunos puntos muertos recurrentes, uno de los cuales es un bloqueo de teclas y contiene una consulta SELECT con una sugerencia de XLOCK que se convierte en la víctima del bloqueo. La otra instrucción es un INSERT en una de las tablas que forma parte de la vista de la primera consulta.
Ver:
create view dbo.viewE
as
select * from dbo.E
where myValue > 13000
Seleccionar consulta:
select * from dbo.viewE with (XLOCK) where A > GETUTCDATE()
INSERTAR declaración:
INSERT INTO [dbo].[E] (myValue,A) VALUES (10,GetDate())
La tabla subyacente dbo.E contiene aproximadamente 3 millones de filas en aproximadamente 20 columnas, algunas de ellas son ntext.
Sacando las consultas y simulándolas manualmente con dos transacciones, el comportamiento es reproducible. El comportamiento cambia si XLOCK se elimina de la selección.
Gráfico de punto muerto:
<deadlock-list>
<deadlock victim="process222222221">
<process-list>
<process id="process222222221" taskpriority="0" logused="0" waitresource="KEY: 5:72057604035644444 (ccdf51accc0c)" waittime="2522" ownerId="27202256401" transactionname="SELECT" lasttranstarted="2015-09-14T16:32:36.160" XDES="0x2f1ec5ca0" lockMode="RangeX-X" schedulerid="15" kpid="12936" status="suspended" spid="359" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2015-09-14T16:32:36.160" lastbatchcompleted="2015-09-14T16:32:36.160" clientapp="x" hostname="x" hostpid="14536" loginname="x" isolationlevel="serializable (4)" xactid="27202256401" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="48" sqlhandle="0x02000000611e4523142b2318c47c87313a9b2ba587ff3130">
SELECT * FROM viewE WITH (XLOCK) WHERE A < GetUtcDate() </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@UICulture nvarchar(5))SELECT * FROM viewE WITH (XLOCK) WHERE A < GetUtcDate() </inputbuf>
</process>
<process id="process6022222" taskpriority="0" logused="161152" waitresource="KEY: 5:72057604035644444 (cd874c2ba438)" waittime="1370" ownerId="27202248438" transactionguid="0x8de5ccd6eeef67469c6234af59e44ca5" transactionname="DTCXact" lasttranstarted="2015-09-14T16:32:34.767" XDES="0x4aa0bf950" lockMode="RangeI-N" schedulerid="14" kpid="6636" status="suspended" spid="329" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2015-09-14T16:32:37.300" lastbatchcompleted="2015-09-14T16:32:37.300" clientapp="x" hostname="x" hostpid="14536" loginname="x" isolationlevel="read uncommitted (1)" xactid="27202248438" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="936" sqlhandle="0x020000004853462f09790a4ddedc0d574c2afa539aef1c0e">
INSERT INTO [E] ([a], [b], [c],...) VALUES (@aDate, @bDate, @c, ...)
</frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>INSERT INTO [E] ([a], [b], [c],...) VALUES (@aDate, @bDate, @c, ...)
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057604035644444" dbid="5" objectname="db.dbo.E" indexname="IX_index1" id="lock258b6dc80" mode="X" associatedObjectId="72057604035644444">
<owner-list>
<owner id="process6022222" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process222222221" mode="RangeX-X" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057604035644444" dbid="5" objectname="db.dbo.E" indexname="IX_index1" id="lock7b145c400" mode="RangeX-X" associatedObjectId="72057604035644444">
<owner-list>
<owner id="process222222221" mode="RangeX-X"/>
</owner-list>
<waiter-list>
<waiter id="process6022222" mode="RangeI-N" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
Hasta donde entiendo esto, estoy viendo un punto muerto KEYLOCK causado básicamente por una consulta de índice descubierta que usa un índice no agrupado y un índice agrupado para recopilar los valores requeridos, ¿verdad?
Mis preguntas:
- No puedo crear un índice de cobertura debido a las columnas NTEXT requeridas involucradas. ¿Reducirá drásticamente la cantidad de filas ayudará aquí?
- ¿Hay alguna buena razón por la que simplemente no sé que SELECT se ejecuta con XLOCK? ¿El estancamiento también ocurriría sin XLOCK?