powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Взаимоблокировки
23 сообщений из 23, страница 1 из 1
Взаимоблокировки
    #39689554
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите если у меня в цикле проходит обращение в процедуре и происходит взаимоблокировка, как я могу избежать этого?

Посоветовали concurent dictionary - то я даже нагуглить не смог

Пробовал SERIALIZABLE - не помогло
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689558
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начните, для начала, с публикации сообщения об ошибке.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689560
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0,

ConcurrentDictionary это вроде как из C#, вам точно это для SQL Server посоветовали?
https://msdn.microsoft.com/ru-ru/library/dd287191(v=vs.110).aspx

Вам вероятно придется код скинуть этих процедур, иначе сложно помочь.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689632
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да вот я тоже увидел что это для C, сначала я пытался эмитировать взаимо блокировку, а теперь нужно решение как обойти))

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
	SET NOCOUNT ON;
	
	set xact_abort on; -- специально 
	
		begin TRANSACTION
		
Какой то код ...
		
		commit transaction;

	
	return 0
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689633
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В том то и дело, что ошибки у меня нету, но когда выполняется в цикле то иногда выдает "0"
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689648
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0, ваш поток сознания слишком мутный, чтобы в нем что-то углядеть.
Взаимоблокировка имеет четкое определение и всегда заканчивается тем, что один из потоков отстреливается с соответствующей ошибкой.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689649
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня цикл включается в API и потом пуляет на SQL я просто тупо не знаю как мне увидеть эту взаимоблокировку.

Когда во время своего цикла я нажимаю sp_lock то показывает очень много Х

Я смотрел в Управление - Журнале MS SQL но так не чего и не увидел там

Ошибки происходят 100, потому что из цикла к примеру на 100 оборотов, добавляет в базу только 70+-, а должен добавить 100

И тут вопрос толи он не успевает добавить в базу, то ли взаимо блокировки но где ошибку посмотреть
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689650
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так разберитесь в вашем API, как получать ошибки, и залогируйте их.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689658
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Такс отлично, ошибок я получил 180 штук, все идентичны

"Транзакция (идентификатор процесса РАЗНОЕ ЧИСЛО) вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки. Запустите транзакцию повторно."

Теперь мы уверены что это взаимно блокировки, теперь если я подниму уровень изоляции до Repetable Read это меня спасет?
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689660
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SERIALIZABLE даже он не помог :(
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689665
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот код

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
	SET NOCOUNT ON;
	
	set xact_abort on;
	
		begin TRANSACTION
		
    	insert into dbo.City([From])
		select @from
		
		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @Id)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @Id, -@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum - @sum
			WHERE id = @Id
		END


		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @Id)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @Id, -@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum - @sum
			WHERE id = @Id
		END

		
		commit transaction;;

	
	return 0
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689669
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если все 3 блока разбить на отдельные транзакции все будет работать, скажите правильно ли это?
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689744
nvv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nvv
Гость
Pabl0, вероятно две сессии пишут один id. Или по id нет индекса.
Очевидно же, что дедлок на апдейте.
Serializable - помочь не сможет, на блокировке диапазонов сделает только хуже.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689748
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0Вот код

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
	SET NOCOUNT ON;
	
	set xact_abort on;
	
		begin TRANSACTION
		
    	insert into dbo.City([From])
		select @from
		
		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @Id)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @Id, -@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum - @sum
			WHERE id = @Id
		END


		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @Id)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @Id, -@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum - @sum
			WHERE id = @Id
		END

		
		commit transaction;;

	
	return 0



Ну, если у вас все верно написано - это эвивалентно

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
begin TRANSACTION;
            
		
    	    insert into dbo.City([From])
		    select @from;
		
		
            with t as ( SELECT * FROM Estimate  )
               , x as ( SELECT id = @Id, sum = - @sum )
              merge t using x on t.id = x.id
                when not matched then insert(id, sum) values(id, sum)
                when matched then update set sum = sum + 2 * x.sum
		
commit transaction;
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689878
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nvv, да, я с вами полностью согласен на изменении дедлоки
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689879
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222, я сильно извиняюсь, но с кодом ппц намудрил, вот как должно быть

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
	SET NOCOUNT ON;
	
	set xact_abort on;
	
		begin TRANSACTION
		
    	insert into dbo.City([From])
		select @from
		
		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @to)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @to, -@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum - @sum
			WHERE id = @to
		END


		IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @from)
		BEGIN
			INSERT INTO Estimate (id, sum)
			SELECT @from, +@sum
		END 
		ELSE 
		BEGIN
			UPDATE Estimate
				SET sum = sum + @sum
			WHERE id = @ from
		END

		
		commit transaction;;

	
	return 0



извините еще раз пожалуйста
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689894
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0,

Замените вашу череду excists/insert/update на это
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
merge into Estimate t
using
(
 values
  (@from, @sum), (@to, -@sum)
) s(id, sum)
when not matched then
 insert (id, sum) values (s.id, s.sum)
when matched then
 update set sum += s.sum;


О дедлоке можно предметно говорить, если покажете его граф (в виде ml, картинка бесполезна).
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689972
Pabl0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если как я сделал в отдельные транзакции это не правильно?
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39689984
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0,

Если логика позволяет сделать без одной общей транзакции, т.е. каждый стейтмент в отдельной транзакции (кстати явно транзакцию для одного стейтмента указывать не нужно), то это вероятно будет работать, дедлоков не должно быть.

Лучше попробуйте разобраться с предложенным merge решением. Вы сохраняете транзакцию и не делаете лишних движений.
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39690000
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0А если как я сделал в отдельные транзакции это не правильно?Ну если вам наплевать, что, например, к @from @sum прибавится, а от @to @sum не отнимется, то можете вообще не заморачиваться с транзакциями.

Если таки решите разобраться с транзакциями и дедлоками, то мой пример лучше переписать так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare @s table (id ... primary key, sum ...);
insert into @s
values
 (@from, @sum), (@to, -@sum)

merge into Estimate t
using @s s on s.id = t.id
when not matched then
 insert (id, sum) values (s.id, s.sum)
when matched then
 update set sum += s.sum;


ЗЫ: А исходный пример надо бы поправить
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
merge into Estimate t
using
(
 values
  (@from, @sum), (@to, -@sum)
) s(id, sum) s on s.id = t.id
when not matched then
 insert (id, sum) values (s.id, s.sum)
when matched then
 update set sum += s.sum;
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39690243
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmлучше переписать так
Поясните пожалуйста почему лучше?
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39690248
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир ЗатуливетерПоясните пожалуйста почему лучше?Чтобы снизить вероятность дедлока, если несколько сессий пересекуться по (@from, @to).
...
Рейтинг: 0 / 0
Взаимоблокировки
    #39690434
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pabl0,

Код: sql
1.
IF NOT EXISTS(SELECT * FROM Estimate (NOLOCK) a WHERE a.id = @from)



(NOLOCK) не используйте в процедурах, изменяющих данные или готовящих изменения. Потом будете списывать загадочные случаи на "компьютерный сбой" :)
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Взаимоблокировки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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