Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Дэдлок писателей в БД ReportServerTempDB  [new]
sps777
Member

Откуда:
Сообщений: 14
Привожу файл графа дэдлока (он небольшой),
вот та же инфа в XML:
+
<deadlock>
<victim-list>
<victimProcess id="process1e08743848" />
<victimProcess id="process8bb66cca8" />
</victim-list>
<process-list>
<process id="process1e08743848" taskpriority="0" logused="0" waitresource="KEY: 6:72057594043301888 (975922a7848b)" waittime="1632" ownerId="2391059109" transactionname="user_transaction" lasttranstarted="2021-04-02T12:35:07.783" XDES="0xe30748970" lockMode="U" schedulerid="8" kpid="39844" status="suspended" spid="93" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-04-02T12:35:07.783" lastbatchcompleted="2021-04-02T12:35:07.783" lastattention="1900-01-01T00:00:00.783" clientapp="Report Server" hostname="SL01537" hostpid="24252" loginname="NT SERVICE\ReportServer" isolationlevel="read committed (2)" xactid="2391059109" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="ReportServer.dbo.DereferenceSessionSnapshot" line="16" stmtstart="752" stmtend="1302" sqlhandle="0x030005001c5c8438b3fb3201d4a6000001000000000000000000000000000000000000000000000000000000"> UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM [ReportServerTempDB].dbo.SnapshotData AS SN INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID WHERE SE.SessionID = @SessionID AND SE.OwnerID = @OwnerI </frame>
<frame procname="ReportServer.dbo.ClearSessionSnapshot" line="13" stmtstart="590" stmtend="700" sqlhandle="0x0300050056c60d42c0fb3201d4a6000001000000000000000000000000000000000000000000000000000000"> EXEC DereferenceSessionSnapshot @SessionID, @OwnerID </frame>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 1108198998] </inputbuf>
</process>
<process id="process8bb66cca8" taskpriority="0" logused="0" waitresource="KEY: 6:72057594043301888 (975922a7848b)" waittime="1632" ownerId="2391059218" transactionname="user_transaction" lasttranstarted="2021-04-02T12:35:07.843" XDES="0x2d9191a040" lockMode="U" schedulerid="1" kpid="22812" status="suspended" spid="77" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-04-02T12:35:07.843" lastbatchcompleted="2021-04-02T12:35:07.843" lastattention="1900-01-01T00:00:00.843" clientapp="Report Server" hostname="SL01537" hostpid="24252" loginname="NT SERVICE\ReportServer" isolationlevel="read committed (2)" xactid="2391059218" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="ReportServer.dbo.DereferenceSessionSnapshot" line="16" stmtstart="752" stmtend="1302" sqlhandle="0x030005001c5c8438b3fb3201d4a6000001000000000000000000000000000000000000000000000000000000"> UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM [ReportServerTempDB].dbo.SnapshotData AS SN INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID WHERE SE.SessionID = @SessionID AND SE.OwnerID = @OwnerI </frame>
<frame procname="ReportServer.dbo.ClearSessionSnapshot" line="13" stmtstart="590" stmtend="700" sqlhandle="0x0300050056c60d42c0fb3201d4a6000001000000000000000000000000000000000000000000000000000000"> EXEC DereferenceSessionSnapshot @SessionID, @OwnerID </frame>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 1108198998] </inputbuf>
</process>
<process id="process22a01908c8" taskpriority="0" logused="592" waitresource="KEY: 6:72057594040745984 (aed6c0e5137d)" waittime="1632" ownerId="2391059166" transactionname="user_transaction" lasttranstarted="2021-04-02T12:35:07.810" XDES="0x19c62630a0" lockMode="X" schedulerid="2" kpid="38184" status="suspended" spid="73" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2021-04-02T12:35:07.810" lastbatchcompleted="2021-04-02T12:35:07.810" lastattention="1900-01-01T00:00:00.810" clientapp="Report Server" hostname="SL01537" hostpid="24252" loginname="NT SERVICE\ReportServer" isolationlevel="read committed (2)" xactid="2391059166" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="ReportServer.dbo.ClearSessionSnapshot" line="15" stmtstart="702" stmtend="1426" sqlhandle="0x0300050056c60d42c0fb3201d4a6000001000000000000000000000000000000000000000000000000000000"> UPDATE SE SET SE.SnapshotDataID = null, SE.IsPermanentSnapshot = null, SE.SnapshotExpirationDate = null, SE.ShowHideInfo = null, SE.HasInteractivity = null, SE.AutoRefreshSeconds = null, SE.Expiration = @Expiration FROM [ReportServerTempDB].dbo.SessionData AS SE WHERE SE.SessionID = @SessionID AND SE.OwnerID = @OwnerI </frame>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 1108198998] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594043301888" dbid="6" objectname="ReportServerTempDB.dbo.SnapshotData" indexname="IX_SnapshotData" id="lock2a9c434800" mode="X" associatedObjectId="72057594043301888">
<owner-list>
<owner id="process8bb66cca8" mode="U" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="process1e08743848" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594043301888" dbid="6" objectname="ReportServerTempDB.dbo.SnapshotData" indexname="IX_SnapshotData" id="lock2a9c434800" mode="X" associatedObjectId="72057594043301888">
<owner-list>
<owner id="process22a01908c8" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process8bb66cca8" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594040745984" dbid="6" objectname="ReportServerTempDB.dbo.SessionData" indexname="IDX_SessionData" id="lock2baca83f00" mode="U" associatedObjectId="72057594040745984">
<owner-list>
<owner id="process1e08743848" mode="S" />
</owner-list>
<waiter-list>
<waiter id="process22a01908c8" mode="X" requestType="convert" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>

и вот тексты двух маленьких процедур, которые там в <executionStack>:
+
CREATE PROCEDURE [dbo].[ClearSessionSnapshot]
@SessionID as varchar(32),
@OwnerSid as varbinary(85) = NULL,
@OwnerName as nvarchar(260),
@AuthType as int,
@Expiration as datetime
AS

DECLARE @OwnerID uniqueidentifier
EXEC GetUserID @OwnerSid, @OwnerName, @AuthType, @OwnerID OUTPUT

EXEC DereferenceSessionSnapshot @SessionID, @OwnerID

UPDATE SE
SET
SE.SnapshotDataID = null,
SE.IsPermanentSnapshot = null,
SE.SnapshotExpirationDate = null,
SE.ShowHideInfo = null,
SE.HasInteractivity = null,
SE.AutoRefreshSeconds = null,
SE.Expiration = @Expiration
FROM
[ReportServerTempDB].dbo.SessionData AS SE
WHERE
SE.SessionID = @SessionID AND
SE.OwnerID = @OwnerID

-----------------------------------------------------------------------------------------------

CREATE PROCEDURE [dbo].[DereferenceSessionSnapshot]
@SessionID as varchar(32),
@OwnerID as uniqueidentifier
AS

UPDATE SN
SET TransientRefcount = TransientRefcount - 1
FROM
SnapshotData AS SN
INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID
WHERE
SE.SessionID = @SessionID AND
SE.OwnerID = @OwnerID

UPDATE SN
SET TransientRefcount = TransientRefcount - 1
FROM
[ReportServerTempDB].dbo.SnapshotData AS SN
INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID
WHERE
SE.SessionID = @SessionID AND
SE.OwnerID = @OwnerID

-----------------------------------------------------------------------------------------------

структуры таблиц с индексами:
+
CREATE TABLE [dbo].[SessionData](
[SessionID] [varchar](32) NOT NULL,
[CompiledDefinition] [uniqueidentifier] NULL,
[SnapshotDataID] [uniqueidentifier] NULL,
[IsPermanentSnapshot] [bit] NULL,
[ReportPath] [nvarchar](464) NULL,
[Timeout] [int] NOT NULL,
[AutoRefreshSeconds] [int] NULL,
[Expiration] [datetime] NOT NULL,
[ShowHideInfo] [image] NULL,
[DataSourceInfo] [image] NULL,
[OwnerID] [uniqueidentifier] NOT NULL,
[EffectiveParams] [ntext] NULL,
[CreationTime] [datetime] NOT NULL,
[HasInteractivity] [bit] NULL,
[SnapshotExpirationDate] [datetime] NULL,
[HistoryDate] [datetime] NULL,
[PageHeight] [float] NULL,
[PageWidth] [float] NULL,
[TopMargin] [float] NULL,
[BottomMargin] [float] NULL,
[LeftMargin] [float] NULL,
[RightMargin] [float] NULL,
[AwaitingFirstExecution] [bit] NULL,
[EditSessionID] [varchar](32) NULL,
[DataSetInfo] [varbinary](max) NULL,
[SitePath] [nvarchar](440) NULL,
[SiteZone] [int] NOT NULL,
[ReportDefinitionPath] [nvarchar](464) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO


CREATE UNIQUE CLUSTERED INDEX [IDX_SessionData] ON [dbo].[SessionData]
(
[SessionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


CREATE NONCLUSTERED INDEX [IX_EditSessionID] ON [dbo].[SessionData]
(
[EditSessionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


CREATE NONCLUSTERED INDEX [IX_SessionCleanup] ON [dbo].[SessionData]
(
[Expiration] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


CREATE NONCLUSTERED INDEX [IX_SessionSnapshotID] ON [dbo].[SessionData]
(
[SnapshotDataID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

ALTER TABLE [dbo].[SessionData] ADD DEFAULT ((0)) FOR [SiteZone]
GO

--------------------------------------------------------------------------

CREATE TABLE [dbo].[SnapshotData](
[SnapshotDataID] [uniqueidentifier] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[ParamsHash] [int] NULL,
[QueryParams] [ntext] NULL,
[EffectiveParams] [ntext] NULL,
[Description] [nvarchar](512) NULL,
[DependsOnUser] [bit] NULL,
[PermanentRefcount] [int] NOT NULL,
[TransientRefcount] [int] NOT NULL,
[ExpirationDate] [datetime] NOT NULL,
[PageCount] [int] NULL,
[HasDocMap] [bit] NULL,
[Machine] [nvarchar](512) NOT NULL,
[PaginationMode] [smallint] NULL,
[ProcessingFlags] [int] NULL,
[IsCached] [bit] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO


CREATE CLUSTERED INDEX [IX_SnapshotData] ON [dbo].[SnapshotData]
(
[SnapshotDataID] ASC,
[ParamsHash] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


CREATE NONCLUSTERED INDEX [IS_SnapshotExpiration] ON [dbo].[SnapshotData]
(
[PermanentRefcount] ASC,
[ExpirationDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


CREATE NONCLUSTERED INDEX [IX_SnapshotCleaning] ON [dbo].[SnapshotData]
(
[PermanentRefcount] ASC,
[TransientRefcount] ASC
)
INCLUDE ( [Machine]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

ALTER TABLE [dbo].[SnapshotData] ADD DEFAULT ((0)) FOR [IsCached]
GO


Поясните, плиз, как могут здесь появляться такие блокировки, почему например spid 93 держит U-lock на IDX_SessionData ?
spid 73 не отпускает X-lock на IX_SnapshotData, п.ч. всё выполняется в какой-то внешней транзакции ?
И почему в дэдлоке две жертвы ?

К сообщению приложен файл (xmlresult13.xdl - 6Kb) cкачать
25 апр 21, 11:41    [22313870]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
invm
Member

Откуда: Москва
Сообщений: 9725
sps777
почему например spid 93 держит U-lock на IDX_SessionData ?
Он держит S на IDX_SessionData.
И ждет U на IX_SnapshotData.
sps777
spid 73 не отпускает X-lock на IX_SnapshotData
X в любом случае удерживается до конца транзакции.
sps777
И почему в дэдлоке две жертвы ?
Нужно завершить два процесса, чтобы ушли все ожидания блокировок.
25 апр 21, 21:41    [22314066]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
sps777
Member

Откуда:
Сообщений: 14
invm
sps777
почему например spid 93 держит U-lock на IDX_SessionData ?
Он держит S на IDX_SessionData.

Тогда что означает mode="U" в <keylock> (в спойлере), кто его держит ?
+
<keylock hobtid="72057594040745984" dbid="6" objectname="ReportServerTempDB.dbo.SessionData" indexname="IDX_SessionData" id="lock2baca83f00" mode="U" associatedObjectId="72057594040745984">
<owner-list>
<owner id="process1e08743848" mode="S" />
</owner-list>
<waiter-list>
<waiter id="process22a01908c8" mode="X" requestType="convert" />
</waiter-list>
</keylock>

invm

sps777
spid 73 не отпускает X-lock на IX_SnapshotData
X в любом случае удерживается до конца транзакции.
В процедурах нет BEGIN TRAN - т.е. вызов всего этого, надо предположить, обернут в транзакцию ?
invm
sps777
И почему в дэдлоке две жертвы ?
Нужно завершить два процесса, чтобы ушли все ожидания блокировок.
Смотрю на граф - убиваем 93, 73 получает свой "Request Mode" и освобождает свой "Owner Mode" и, после этого, 77 так же получает свой "Request Mode" и освобождает свой "Owner Mode". Почему так не работает ?
25 апр 21, 23:05    [22314103]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8587
sps777,

уберите вот это
INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID
из update, замените на временную таблицу или включите RCSI.
25 апр 21, 23:42    [22314120]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8587
sps777,

процессы работают не по очереди, а параллельно, нет никакой гарантий - какой из них первым получит блокировку. Выжить должен только один, как в известном фильме.
25 апр 21, 23:45    [22314123]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
invm
Member

Откуда: Москва
Сообщений: 9725
sps777
Тогда что означает mode="U" в <keylock> (в спойлере), кто его держит ?
Вот тут объяснение - https://rusanu.com/2010/05/12/the-puzzle-of-u-locks-in-deadlock-graphs/
sps777
В процедурах нет BEGIN TRAN - т.е. вызов всего этого, надо предположить, обернут в транзакцию ?
Не обязательно. Любой DML выполняется в транзакции. Если нет явной, то будет открыта неявная.
sps777
Смотрю на граф - убиваем 93, 73 получает свой "Request Mode" и освобождает свой "Owner Mode" и, после этого, 77 так же получает свой "Request Mode" и освобождает свой "Owner Mode". Почему так не работает ?
Могу лишь предположить, что в виду критичности длительности выявления жертвы, не тратится время на поиски оптимального варианта.
26 апр 21, 11:24    [22314323]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1757
sps777,

тут вот что странно, последовательность запуска была такой:

processnamespid
process1e0874384893
process8bb66cca8 77
process22a01908c8 73


rn spid event start_time tran_id
1 93 ReportServer.dbo.DereferenceSessionSnapshot 2021-04-02T12:35:07.783 2391059109
2 73 ReportServer.dbo.ClearSessionSnapshot 2021-04-02T12:35:07.810 2391059166
3 77 ReportServer.dbo.ClearSessionSnapshot 2021-04-02T12:35:07.843 2391059218


то есть по последовательности инструкций должна была получаться схема (я предположу что ReportServer неявно открывает пользовательскую транзакцию, и блокировки будут удерживаться)

rn spid stmt lock_object lock_resource lock_mode waits
1 93 exec [dbo].[DereferenceSessionSnapshot]
2 93 /* UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM SnapshotData AS SN */ [SnapshotData] (keylock: IX_SnapshotData) U
2* 93 /* UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM SnapshotData AS SN */ [ReportServerTempDB].dbo.SessionData (keylock: IDX_SessionData) S
2** 93 /* UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM SnapshotData AS SN */ [SnapshotData] (keylock: IX_SnapshotData) convert U->X
3 93 вот на этом этапе интересная ситуация: сессия в режиме изоляции READ COMMITTED U блокировка должна по сути сконвертироваться в X и остаться до окончания транзакции а S сняться после получения
3* 93 на этом этапе мы видим ситуацию из графа дедлока. только здесь у 93 сессии еще должна быть S блокировка на ключ ReportServerTempDB.SessionData которого начинает ожидать сессия 7777 waits 93
5 93 /* UPDATE SN SET TransientRefcount = TransientRefcount - 1 FROM [ReportServerTempDB].dbo.SnapshotData AS SN */ [ReportServerTempDB].dbo.SnapshotData (keylock: IX_SnapshotData) U 93 waits 73


другие сессии не расписывал, они начинают получать свои локи приблизительно одновременно с шагом 2.
явную последовательность получения блокировок далабы xEvent-сессия.
но что мне больше всего интересно как получается так что 93 держит S и в тоже время начинает ждать у от второй инструкции апдейта процедуры


add: АААА все я Вася! сейчас на процу глянул и понял что не туда смотрел. там S блокировка не от первого апдейта а от второго.
UPDATE SN
SET TransientRefcount = TransientRefcount - 1
FROM
[ReportServerTempDB].dbo.SnapshotData AS SN
INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE ON SN.SnapshotDataID = SE.SnapshotDataID

тогда все вполне логично

add2: тогда единственное что меня еще тут смущает в целом структура индексов выстроенна так что коллизий блокировок по ключам быть не должно. получается что у ТС 3 сессии пытались грохнуть (судя по названию процедур) одну и туже сущность иначе бы дедлока не было

Сообщение было отредактировано: 26 апр 21, 15:52
26 апр 21, 15:52    [22314547]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
sps777
Member

Откуда:
Сообщений: 14
felix_ff

предположу что ReportServer неявно открывает пользовательскую транзакцию, и блокировки будут удерживаться

Да, я бы тоже это предположил - на графе spid_73 не может же держать свой "Owner Mode: X" на IX_SnapshotData, если у него текущая инструкция - это update только по табл.SessionData. Значит держит своими предыдущими инструкциями в где-то открытой до этого транзакции.
Пытаться всё представить в хронологии - это прямо глубоко ). Видно, что несмотря на то что 93 стартовал 1-ым, 73 его легко обошел и 1-ым достиг последней инструкции в батче (update se).
В табличке с 6-ю столбцами кажется перепутаны 77 и 73, но не суть.

felix_ff

add2: тогда единственное что меня еще тут смущает в целом структура индексов выстроенна так что коллизий блокировок по ключам быть не должно. получается что у ТС 3 сессии пытались грохнуть (судя по названию процедур) одну и туже сущность иначе бы дедлока не было

что одни и те же сущности - наверное не обязательно даже индексы анализировать, что сам тип блокировки "keylock" это ж тоже об этом говорит.
26 апр 21, 21:51    [22314756]     Ответить | Цитировать Сообщить модератору
 Re: Дэдлок писателей в БД ReportServerTempDB  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1757
sps777
felix_ff

предположу что ReportServer неявно открывает пользовательскую транзакцию, и блокировки будут удерживаться

Да, я бы тоже это предположил - на графе spid_73 не может же держать свой "Owner Mode: X" на IX_SnapshotData, если у него текущая инструкция - это update только по табл.SessionData. Значит держит своими предыдущими инструкциями в где-то открытой до этого транзакции.
Пытаться всё представить в хронологии - это прямо глубоко ). Видно, что несмотря на то что 93 стартовал 1-ым, 73 его легко обошел и 1-ым достиг последней инструкции в батче (update se).
В табличке с 6-ю столбцами кажется перепутаны 77 и 73, но не суть.


да там перепутал.

что одни и те же сущности - наверное не обязательно даже индексы анализировать, что сам тип блокировки "keylock" это ж тоже об этом говорит.

не совсем, у вас и при сканировании индексов будут теже блокировки по ключам если не будет укрупнений.
поэтому здесь важно понимать дают ли предикаты и условия объединений одну строку или несколько.

по SessionData предикат where SE.SessionID = @SessionID AND SE.OwnerID = @OwnerID однозначно установит лок только на единственный ключ, а вот предикат соединения ON SN.SnapshotDataID = SE.SnapshotDataID по сути может блокировать несколько ключей индекс там не уникальный.

но у вас по большей части проблема дедлока из-за преобразования U->X

в теории вам было бы достаточно несколько изменить инструкцию второго апдейта:
UPDATE SN
SET TransientRefcount = TransientRefcount - 1
FROM
[ReportServerTempDB].dbo.SnapshotData AS SN
INNER JOIN [ReportServerTempDB].dbo.SessionData AS SE WITH(UPDLOCK) ON SN.SnapshotDataID = SE.SnapshotDataID
WHERE
SE.SessionID = @SessionID AND
SE.OwnerID = @OwnerID


или понять причины нафига несколько сессий одновременно ломатся за этой сущностью.
26 апр 21, 22:18    [22314772]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить