Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с deadlock PK Index / 25 сообщений из 40, страница 1 из 2
16.02.2018, 12:49
    #39602889
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Добрый день!

Кто может подсказать почему возникает deadlock и можно ли его побороть.

Согласно графу deadlock происходит Key Lock индекса PK_Calculation.

В БД выполняется сохранение связанных данных:
1. Идёт вставка 1 записи в таблицу Data.Calculation
2. Идёт вставка множества записей в таблицы, которые связанны с таблицей Data.Calculation по внешнему ключу (FK_Calculation_....)

Все deadlock одинаковые.

В приложении граф deadlock.
...
Рейтинг: 0 / 0
16.02.2018, 12:51
    #39602891
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Картинка deadlock
...
Рейтинг: 0 / 0
16.02.2018, 13:30
    #39602930
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

имхо
INSERT INTO Data.Calculation WITH (ROWLOCK, HOLDLOCK)
...
Рейтинг: 0 / 0
16.02.2018, 14:47
    #39603012
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov2. Идёт вставка множества записей в таблицы, которые связанны с таблицей Data.Calculation по внешнему ключу (FK_Calculation_....)И они пересекаются по CalculationId с данными, вставленными в Data.Calculation в других соединениях?
...
Рейтинг: 0 / 0
16.02.2018, 14:59
    #39603028
Помогите с deadlock PK Index
TaPaK,

помочь может как раз наоборот принудительная ескалация вверх
...
Рейтинг: 0 / 0
16.02.2018, 15:01
    #39603033
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Согласно графу deadlockTaPaK,

помочь может как раз наоборот принудительная ескалация вверх
то таки вы тока ROWLOCK видите? или всё лечим табоками?
...
Рейтинг: 0 / 0
16.02.2018, 15:11
    #39603043
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
invm,

Нет, данные с другими соединениям не пересекаются, в каждом соединении используется свой CalсulationId.
Есть таблица Data.Calculation которая описывает шапку расчёта и 4 таблицы в одной их которых содержатся результаты расчёта и входные данные расчёта. Как раз в этих 4 таблицах используется CalсulationId как внешний ключ для результатов и входных данных.
...
Рейтинг: 0 / 0
16.02.2018, 15:13
    #39603049
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
TaPaK,

После применения старые блокировки не ушли а добавились новые.
...
Рейтинг: 0 / 0
16.02.2018, 15:19
    #39603062
Помогите с deadlock PK Index
egorrezchikov,

я б предложил FK или совсем пристрелить (на возможность этого нам намекает название схемы) или отключать на время объемных вставок в зависимые таблицы. Или с той стороны (да в целом хоть с какой) PAGLOCK воткни и попробуй.
...
Рейтинг: 0 / 0
16.02.2018, 15:24
    #39603069
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

а как вы @CalculationId получаете??
...
Рейтинг: 0 / 0
16.02.2018, 15:28
    #39603078
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
TaPaK,

Sequence
...
Рейтинг: 0 / 0
16.02.2018, 15:35
    #39603089
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

покажите весь скрипт
...
Рейтинг: 0 / 0
16.02.2018, 15:43
    #39603105
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Ну это типовая ситуация. Индекс + кластерный индекс процесс пишет и тут же читает + второй такой же процесс.

Скорее всего, поможет покрывающий индекс, дабы правый инсерт с поздапросом не лез в кластерный индекс за недостающими полями.
А ещё лучше перепишите вставку без подзапросов.
...
Рейтинг: 0 / 0
16.02.2018, 15:44
    #39603110
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Владислав КолосовНу это типовая ситуация. Индекс + кластерный индекс процесс пишет и тут же читает + второй такой же процесс.

Скорее всего, поможет покрывающий индекс, дабы правый инсерт с поздапросом не лез в кластерный индекс за недостающими полями.
А ещё лучше перепишите вставку без подзапросов.
т.е. граф не открывали?
...
Рейтинг: 0 / 0
16.02.2018, 15:45
    #39603111
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
TaPaK,

DECLARE @CalculationId int = NEXT VALUE FOR Data.SeqCalculation;

INSERT INTO Data.Calculation WITH (ROWLOCK, HOLDLOCK) (CalculationId, TaskId, DateFrom, DateTo, CalcDateTime, StepTypeId, LocationId, TargetExternalSourceId, Target, Comment, UserProfileId, CalculationSetId)
VALUES (@CalculationId, @TaskId, @DateFrom, @DateTo, @CalcDateTime, @StepTypeId, @LocationId, @TargetExternalSourceId, @Target, @Comment, @UserProfileId, @CalculationSetId);




INSERT INTO Data.CalculationFactor(CalculationFactorId, CalculationId, FactorId, ValueDateTime, Value, ExternalSourceId, IsChanged)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_factor)-1,
@CalculationId, EntityId, ValueDateTime, Value, [Source], 0
FROM @factorData





INSERT INTO Data.CalculationResult(CalculationResultId, CalculationId,ObjectControlId,ValueDateTime,Mdp,Adp,MdpReverse,AdpReverse,IsControlKpos,MdpInstructionValueId,
AdpInstructionValueId, [Rule], MdpOriginal, AdpOriginal,Temperature,MdpMptFormula,ExternalSourceId,InstructionLineRepairId,ArchmState,IrregularFluctuation,MdpClear)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_result)-1,
@CalculationId,ObjectControlId,ValueDateTime,MdpValue,AdpValue,null,null,IsControlled,MdpInstructionValueId,AdpInstructionValueId,
[Rule], MdpOriginalValue, AdpOriginalValue,Temperature,MdpMptFormula,[Source],RepairSchemaId,ArchmState,IrregularFluctuation,MdpClear
FROM @resultValue
...
Рейтинг: 0 / 0
16.02.2018, 15:47
    #39603116
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
в общую транзакцию оберните
...
Рейтинг: 0 / 0
16.02.2018, 15:49
    #39603118
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

так а где ваше Meteo?
...
Рейтинг: 0 / 0
16.02.2018, 15:54
    #39603128
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
TaPaK,

Полная версия тела ХП


SET NOCOUNT ON;

SET XACT_ABORT ON;

DECLARE @TaskCode varchar(50);
SET @TaskCode = (SELECT Code FROM Sec.Task WITH(NOLOCK) WHERE TaskId = @TaskId)

DECLARE @ErrorMessage varchar(8000),@ErrorSeverity INT,@ErrorState INT,@ErrorNumber INT;
DECLARE @timeout varchar(20)
declare @rc int = 0 -- return code

DECLARE @triesMax int = 10;
DECLARE @tries int
SET @tries = 0
WHILE @tries<@triesMax
BEGIN

BEGIN TRY
BEGIN TRAN

DECLARE
@sequence_name nvarchar(100),
@range_size int,
@range_first_value_factor sql_variant,
@range_first_value_meteo sql_variant,
@range_first_value_ne sql_variant,
@range_first_value_result sql_variant,
@range_last_value sql_variant,
@sequence_increment sql_variant,
@sequence_min_value sql_variant,
@sequence_max_value sql_variant;

SET @sequence_name = 'Data.SeqCalculationFactor'
select @range_size = count(*) from @factorData
if @range_size>0
EXEC sp_sequence_get_range
@sequence_name = @sequence_name,
@range_size = @range_size,
@range_first_value = @range_first_value_factor OUTPUT,
@range_last_value = @range_last_value OUTPUT, @sequence_increment = @sequence_increment OUTPUT,@sequence_min_value = @sequence_min_value OUTPUT,@sequence_max_value = @sequence_max_value OUTPUT;

SET @sequence_name = 'Data.SeqCalculationResultMeteo'
select @range_size = count(*) from @meteoData
if @range_size>0
EXEC sp_sequence_get_range
@sequence_name = @sequence_name,
@range_size = @range_size,
@range_first_value = @range_first_value_meteo OUTPUT,
@range_last_value = @range_last_value OUTPUT, @sequence_increment = @sequence_increment OUTPUT,@sequence_min_value = @sequence_min_value OUTPUT,@sequence_max_value = @sequence_max_value OUTPUT;

SET @sequence_name = 'Data.SeqCalculationNetElement'
select @range_size = count(*) from @repairPoint
if @range_size>0
EXEC sp_sequence_get_range
@sequence_name = @sequence_name,
@range_size = @range_size,
@range_first_value = @range_first_value_ne OUTPUT,
@range_last_value = @range_last_value OUTPUT, @sequence_increment = @sequence_increment OUTPUT,@sequence_min_value = @sequence_min_value OUTPUT,@sequence_max_value = @sequence_max_value OUTPUT;

SET @sequence_name = 'Data.SeqCalculationResult'
select @range_size = count(*) from @resultValue
if @range_size>0
EXEC sp_sequence_get_range
@sequence_name = @sequence_name,
@range_size = @range_size,
@range_first_value = @range_first_value_result OUTPUT,
@range_last_value = @range_last_value OUTPUT, @sequence_increment = @sequence_increment OUTPUT,@sequence_min_value = @sequence_min_value OUTPUT,@sequence_max_value = @sequence_max_value OUTPUT;

IF 1 = 1
BEGIN

DECLARE @CalcDateTime datetime = GETUTCDATE();

DECLARE @StepTypeId int = '24';

DECLARE @TargetExternalSourceId int = NULL;
DECLARE @Target varchar(850) = NULL;

DECLARE @CalculationId int = NEXT VALUE FOR Data.SeqCalculation;

INSERT INTO Data.Calculation WITH (ROWLOCK, HOLDLOCK) (CalculationId, TaskId, DateFrom, DateTo, CalcDateTime, StepTypeId, LocationId, TargetExternalSourceId, Target, Comment, UserProfileId, CalculationSetId)
VALUES (@CalculationId, @TaskId, @DateFrom, @DateTo, @CalcDateTime, @StepTypeId, @LocationId, @TargetExternalSourceId, @Target, @Comment, @UserProfileId, @CalculationSetId);
END


IF 1 = 1
BEGIN

INSERT INTO Data.CalculationFactor(CalculationFactorId, CalculationId, FactorId, ValueDateTime, Value, ExternalSourceId, IsChanged)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_factor)-1,
@CalculationId, EntityId, ValueDateTime, Value, [Source], 0
FROM @factorData

END


IF 1 = 1
BEGIN
INSERT INTO Data.CalculationResultMeteo(CalculationResultMeteoId, CalculationId, MeteoPointId, EnergySystemId,ValueDateTime, MeteoTypeId, Value)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_meteo)-1,
@CalculationId,
CASE WHEN @TaskCode = '2' OR @TaskCode = '1' THEN EntityId ELSE NULL END AS MeteoPointId,
CASE WHEN @TaskCode = '3' THEN EntityId ELSE NULL END AS EnergySystemId,
ValueDateTime, null, Value
FROM @meteoData
where Value is not null or @TaskCode = '2' OR @TaskCode = '1'
END


IF 1 = 1
BEGIN
INSERT INTO Data.CalculationNetElement(CalculationNetElementId, CalculationId, NetElementId, ValueDateTime,
Value, ExternalSourceId, IsChanged)
SELECT ROW_NUMBER() OVER(ORDER BY PointDate)+ CONVERT(bigint,@range_first_value_ne)-1,
@CalculationId, NetElementId, PointDate,
1, [Source], IsChanged FROM @repairPoint
END


IF 1 = 1
BEGIN
INSERT INTO Data.CalculationResult(CalculationResultId,CalculationId,ObjectControlId,ValueDateTime,Mdp,Adp,MdpReverse,AdpReverse,IsControlKpos,MdpInstructionValueId,
AdpInstructionValueId, [Rule], MdpOriginal, AdpOriginal,Temperature,MdpMptFormula,ExternalSourceId,InstructionLineRepairId,ArchmState,IrregularFluctuation,MdpClear)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_result)-1,
@CalculationId,ObjectControlId,ValueDateTime,MdpValue,AdpValue,null,null,IsControlled,
case when MdpInstructionValueId = 0 then null else MdpInstructionValueId end as MdpInstructionValueId,
case when AdpInstructionValueId = 0 then null else AdpInstructionValueId end as AdpInstructionValueId,
[Rule], MdpOriginalValue, AdpOriginalValue,Temperature,MdpMptFormula,[Source],
case when RepairSchemaId = 0 then null else RepairSchemaId end as RepairSchemaId,
ArchmState,IrregularFluctuation,MdpClear
FROM @resultValue
END

SELECT @CalculationId AS CalculationId

COMMIT TRAN

END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN;
SET @tries = @tries + 1

SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE(),
@ErrorNumber = ERROR_NUMBER();

IF (@ErrorNumber = 1205 OR @ErrorNumber = 1222) AND @tries < @triesMax
begin

set @timeout = '00:00:0'+Substring(CONVERT(varchar(20),RAND()),1,4)
WAITFOR DELAY @timeout
CONTINUE
end
RAISERROR(@ErrorMessage, 16, 1);

END CATCH

BREAK;
END -- TRIES
...
Рейтинг: 0 / 0
16.02.2018, 15:58
    #39603134
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikovDECLARE @CalculationId int = NEXT VALUE FOR Data.SeqCalculation;

INSERT INTO Data.Calculation WITH (ROWLOCK, HOLDLOCK) (CalculationId, TaskId, DateFrom, DateTo, CalcDateTime, StepTypeId, LocationId, TargetExternalSourceId, Target, Comment, UserProfileId, CalculationSetId)
VALUES (@CalculationId, @TaskId, @DateFrom, @DateTo, @CalcDateTime, @StepTypeId, @LocationId, @TargetExternalSourceId, @Target, @Comment, @UserProfileId, @CalculationSetId);




INSERT INTO Data.CalculationFactor(CalculationFactorId, CalculationId, FactorId, ValueDateTime, Value, ExternalSourceId, IsChanged)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_factor)-1,
@CalculationId, EntityId, ValueDateTime, Value, [Source], 0
FROM @factorData





INSERT INTO Data.CalculationResult(CalculationResultId, CalculationId,ObjectControlId,ValueDateTime,Mdp,Adp,MdpReverse,AdpReverse,IsControlKpos,MdpInstructionValueId,
AdpInstructionValueId, [Rule], MdpOriginal, AdpOriginal,Temperature,MdpMptFormula,ExternalSourceId,InstructionLineRepairId,ArchmState,IrregularFluctuation,MdpClear)
SELECT ROW_NUMBER() OVER(ORDER BY ValueDateTime)+ CONVERT(bigint,@range_first_value_result)-1,
@CalculationId,ObjectControlId,ValueDateTime,MdpValue,AdpValue,null,null,IsControlled,MdpInstructionValueId,AdpInstructionValueId,
[Rule], MdpOriginalValue, AdpOriginalValue,Temperature,MdpMptFormula,[Source],RepairSchemaId,ArchmState,IrregularFluctuation,MdpClear
FROM @resultValueВ этом скрипте нет конфликтующих инструкций из графа дедлока.

В общем, конфликтуют у вас для Data.Calculation вставка и чтение при проверке FK.
С учетомegorrezchikovНет, данные с другими соединениям не пересекаются, в каждом соединении используется свой CalсulationId.Такое может происходить если в инструкциях insert для соединения с Data.Calculation при проверке FK используется merge или hash.
Если это так, то можете попробовать вылечить, дописав к инструкциям вставки в подчиненные таблицы option(loop join)
...
Рейтинг: 0 / 0
16.02.2018, 16:10
    #39603151
Maxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
у вас FK чистые или с какими-то глупостями класса каскад делита ?
...
Рейтинг: 0 / 0
16.02.2018, 16:15
    #39603156
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
Maxx,

Да чистые. Вот скрипты на создание


ALTER TABLE [Data].[Calculation] ADD CONSTRAINT [PK_Calculation] PRIMARY KEY CLUSTERED
(
[CalculationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO


ALTER TABLE [Data].[CalculationResult] WITH CHECK ADD CONSTRAINT [FK_Calculation_CalculationResult] FOREIGN KEY([CalculationId])
REFERENCES [Data].[Calculation] ([CalculationId])
GO

ALTER TABLE [Data].[CalculationResult] CHECK CONSTRAINT [FK_Calculation_CalculationResult]
GO

ALTER TABLE [Data].[CalculationResultMeteo] WITH CHECK ADD CONSTRAINT [FK_Calculation_CalculationResultMeteo] FOREIGN KEY([CalculationId])
REFERENCES [Data].[Calculation] ([CalculationId])
GO

ALTER TABLE [Data].[CalculationResultMeteo] CHECK CONSTRAINT [FK_Calculation_CalculationResultMeteo]
GO

ALTER TABLE [Data].[CalculationNetElement] WITH CHECK ADD CONSTRAINT [FK_Calculation_CalculationNetElement] FOREIGN KEY([CalculationId])
REFERENCES [Data].[Calculation] ([CalculationId])
GO

ALTER TABLE [Data].[CalculationNetElement] CHECK CONSTRAINT [FK_Calculation_CalculationNetElement]
GO

ALTER TABLE [Data].[CalculationFactor] WITH CHECK ADD CONSTRAINT [FK_Calculation_CalculationFactor] FOREIGN KEY([CalculationId])
REFERENCES [Data].[Calculation] ([CalculationId])
GO

ALTER TABLE [Data].[CalculationFactor] CHECK CONSTRAINT [FK_Calculation_CalculationFactor]
GO
...
Рейтинг: 0 / 0
16.02.2018, 16:21
    #39603163
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

а для 21197198
xml есть?
...
Рейтинг: 0 / 0
16.02.2018, 16:24
    #39603173
egorrezchikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
TaPaK,

Да есть.
...
Рейтинг: 0 / 0
16.02.2018, 16:35
    #39603187
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с deadlock PK Index
egorrezchikov,

на всю транзакцию SERIALIZABLE

можно убрать WITH (ROWLOCK, HOLDLOCK) или пробовать ставить на все инсёрты
...
Рейтинг: 0 / 0
16.02.2018, 16:44
    #39603195
Помогите с deadlock PK Index
TaPaK,

авторили всё лечим табоками?
Какой нахрен SERIALIZABLE. SingleUser уже давай. Какие к черту ROWLOCK. У него из-за ROWLOCK проблемы и лезут.
SERIALIZABLE при массовых вставках - вообще ни разу не таблок, да? еще и при FK.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с deadlock PK Index / 25 сообщений из 40, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]