Имя: Пароль:
1C
 
Проблема взаимоблокировки (ТЖ)
0 user4fun
 
24.07.18
08:24
Всем здравствуйте!Есть регламентное задание Обмена между ЦБ и РИБ которое иногда зависает и ТЖ выдает вот эту ошибку. Как можно избежать таких ошибок? Всем в заранее спасибо!

10:12.387002-0,EXCP,6,process=rphost,p:processName=Base1C,t:clientID=232,t:applicationName=1CV8,t:computerName=User,t:connectID=130,SessionID=17,Usr=User,dbpid=60,Exception=DataBaseException,Descr='Конфликт блокировок при выполнении транзакции:
Microsoft SQL Server Native Client 11.0: Транзакция (идентификатор процесса 60) вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки. Запустите транзакцию повторно.
HRESULT=80004005, SQLSrvr: SQLSTATE=40001, state=33, Severity=D, native=1205, line=1
'
10:12.387049-0,Context,3,process=rphost,p:processName=Base1C ,t:clientID=232,t:applicationName=1CV8,t:computerName=User,t:connectID=130,SessionID=17,Usr=User,Context='
Документ.ПоступлениеТоваров.Форма.ФормаДокумента.Форма : 328 : ТоварыПриИзмененииНоменклатуры(СтрокаТабличнойЧасти);
    Документ.ПоступлениеТоваров.Форма.ФормаДокумента.Форма : 262 : ХарактеристикаНоменклатурыОбъект.Записать();'
1 H A D G E H O G s
 
24.07.18
09:08
(0) Это практически невозможно объяснить, надо смотреть код.
2 H A D G E H O G s
 
24.07.18
09:10
Ну или набраться терпения и собирать граф взаимоблокировки в sql profiler. Долго, но надёжно.
3 user4fun
 
24.07.18
09:16
(2) Подскажите по каким событиям смотреть в Profiler?
4 H A D G E H O G s
 
24.07.18
09:19
Граф взаимоблокировки. Так и называется.
5 user4fun
 
24.07.18
09:38
(4) Спасибо! запустил, отслеживаю.
6 mr freeman
 
24.07.18
10:13
(5) не занимайся дичью. Открой сессию extended events system_health, найди там deadlock report
А какая версия платформы?
7 user4fun
 
24.07.18
10:13
(6) 1С:Предприятие 8.3 (8.3.8.2322)
8 mr freeman
 
24.07.18
10:17
(6) оч. странно что возник дедлок на субд. По репорту надо понять причину, их м.б. 2, найди репорт, сохрани в XML и выложи
9 H A D G E H O G s
 
24.07.18
10:18
(8) Повышение уровня изоляции, почти наверняка запрос в обработчике записи.
10 mr freeman
 
24.07.18
10:27
У него дэдлок на СУБД, а не на сервере 1С. На управляемых до этого не должно доходить. Нужен репорт.
11 H A D G E H O G s
 
24.07.18
10:29
(10) Да вы капитан очевидность, с чего бы я его послал за графом в profiler ? И на управляемых deadlock на СУБД бывает.
12 user4fun
 
24.07.18
10:32
(10) У меня обычные формы. Как можно тут прикрепить файл xml?
13 mr freeman
 
24.07.18
10:34
(11)в обозначенном тобой кейсе дэдлок возник бы на сервере 1с. У него 8.3 и версионирование, с чего им быть?
14 mr freeman
 
24.07.18
10:34
(12) режим совместимости 8.2? Выложи на облако мэйл.ру
15 Вафель
 
24.07.18
10:35
(14) переходи на режим 8.3
16 Вафель
 
24.07.18
10:35
ну или просто можно включить версионирование, если упр блокировки
17 user4fun
 
24.07.18
10:39
(14) Режим совместимости интерфейса 8.2, Режим совместимости 8.3.5.  https://cloud.mail.ru/public/2cPo/aRNvqofMC
18 H A D G E H O G s
 
24.07.18
10:59
Двое ребят захотели почитать и записать свои изменения в планы обмена.
19 user4fun
 
24.07.18
11:01
(18) Как быть в этой ситуации?
20 H A D G E H O G s
 
24.07.18
11:06
(19)

а) 8.3
б) ручной перевод в snapshot
в) в передзаписью выполнять запрос выборки всех полей из планов обмена с опцией ДЛЯ ИЗМЕНЕНИЯ
21 H A D G E H O G s
 
24.07.18
11:06
и отбором по ссылке
22 МешочекЗнаний
 
24.07.18
11:09
(21) Снимаю шляпу, доходчиво объяснил
23 H A D G E H O G s
 
24.07.18
11:11
(22) Что непонятного? Вот, например так:

Процедура ПередЗаписью(Отказ)
    Запрос=Новый Запрос;
    Запрос.Текст=
    "ВЫБРАТЬ
    |    НоменклатураИзменения.Узел,
    |    НоменклатураИзменения.НомерСообщения,
    |    НоменклатураИзменения.Ссылка
    |ИЗ
    |    Справочник.Номенклатура.Изменения КАК НоменклатураИзменения
    |ГДЕ
    |    НоменклатураИзменения.Ссылка = &Ссылка
    |
    |ДЛЯ ИЗМЕНЕНИЯ
    |    Справочник.Номенклатура.Изменения";
    
    Запрос.УстановитьПараметр("Ссылка",ЭтотОбъект.Ссылка);
    Запрос.Выполнить();
24 H A D G E H O G s
 
24.07.18
11:12
(23) Но, на самом деле, (23) - нужно в самом конце ПередЗаписью(), но до начала ПриЗаписи()
25 МешочекЗнаний
 
24.07.18
11:13
(23) Это была не критика
26 user4fun
 
24.07.18
11:19
(24) В модуль какого объекта это нужно написать?
27 МешочекЗнаний
 
24.07.18
11:23
Запрос.УстановитьПараметр("Ссылка",ЭтотОбъект.Ссылка);
28 user4fun
 
24.07.18
11:25
(27) Это для каждого объекта конфигурации прописывать??
29 mr freeman
 
24.07.18
11:37
Мде...щас тут насоветуют.
Во-первых причина дэдлока-захват ресурсов в разном порядке, а не повышение уровня изоляции, как тут пишет один товарищ.
Во-вторых непонятно откуда эта конструкция with(repeatableread) если платформа на 8.3 и должно быть включено mvcc.

Что скажет запрос
select name, is_read_commited_snapshot_on from sys.databases
30 mr freeman
 
24.07.18
11:39
Блин а какой режим блокировок в свойствах конфигурации???
31 user4fun
 
24.07.18
11:45
(30) Режим блокировок стоит автоматический, а по запросу все базы показывают 0.
32 mr freeman
 
24.07.18
11:47
(31) переводи на управляемый.
33 user4fun
 
24.07.18
11:49
(32) Какие последствия это может повлечь?
34 mr freeman
 
24.07.18
11:49
Проще перевести на управляемый чем разбирать это дерьмо с дэдлоками на автоматическом режиме
35 H A D G E H O G s
 
24.07.18
11:53
(29) Я это писал еще до репорта, не передергивай.
36 H A D G E H O G s
 
24.07.18
11:53
(30) Вот это поворот, да?
37 H A D G E H O G s
 
24.07.18
11:54
(34) Дада, переведите на управляемый, потом через месяцок посмотрим на остатки.
38 H A D G E H O G s
 
24.07.18
11:54
(33) Кривой контроль остатков.
39 H A D G E H O G s
 
24.07.18
11:55
(33) Если перевод имеется ввиду "включил галочку 'Управляемый'"
40 mr freeman
 
24.07.18
12:03
Перевод на управляемый режим подразумевает явную установку упр блокировок где нужно (если типовая то ищешь ДЛЯ ИЗМЕНЕНИЯ и там прописываешь).
Кстати Ежов а где ты видел дэдлоки на субд на упр режиме с вкл mvcc и maxdop 1?
41 mr freeman
 
24.07.18
12:07
Там где нужно это где контроль остатков как правило
42 H A D G E H O G s
 
24.07.18
12:07
(40) deadlock-и видел на упр. режиме, но mvcc скорее всего был еще выключен.
43 mr freeman
 
24.07.18
13:02
(42) похоже что ты их вообще не видел, а только на курсах слышал, т.к. твой совет по добавлению конструкции ДЛЯ ИЗМЕНЕНИЯ не годится для случая с захватом ресурсов в разном порядке.
44 H A D G E H O G s
 
24.07.18
13:03
(43) Видел, видел, не боись. Могу даже показать окошечко 1С-а.
45 H A D G E H O G s
 
24.07.18
13:04
(43) Мой совет дан именно для эскалации уровня, так как пляшем от проблемы, а не гипотезируем, че там в каком порядке захватит план обмена при обмене.
46 mr freeman
 
24.07.18
13:13
Там же 2 таблицы, регистрации изменений и справочника. Что тебе даст
1. U ид1 наложена, X ид2 ждет
2. X ид2 наложена, U ид1 ждет
47 H A D G E H O G s
 
24.07.18
13:16
(46) Если U наложена, X не наложется.
48 H A D G E H O G s
 
24.07.18
13:17
1. U ид1 наложена, X ид2 наложена
2. X ид2 Ждет, U ид1 наложена (или таймаут)
49 mr freeman
 
24.07.18
13:20
(47) а разве в (46) наложилось? А дэдлок есть. Как у ТС. Не видно разве тебе?
50 mr freeman
 
24.07.18
13:21
Х ид2 тоже наложена, это другая таблица
51 mr freeman
 
24.07.18
13:22
Под пунктами 1. и 2. разные таблицы
52 H A D G E H O G s
 
24.07.18
13:23
(51) Я думал, разные транзакции
53 mr freeman
 
24.07.18
13:26
(52) ид1 и ид2 разные транзакции. А эти пункты вставлены в контексте моих слов про 2 таблицы. Так что же делать ТС-у теперь?
54 H A D G E H O G s
 
24.07.18
13:42
На данный момент:
1 транзакция: X Таб2 наложена, X Таб1 ждет (жертва)
2 транзакция: X Таб1 наложена, S Таб2 ждет

Да, я ступил, не посмотрел, что разные таблицы. Это захват ресурсов в разном порядке и ДЛЯ ИЗМЕНЕНИЯ тут не прокатит. Признаю свою ошибку.
55 mr freeman
 
24.07.18
13:48
ТС-у можно посоветовать убрать говнокод по записи характеристики при изменении строки, обмениваться ночью, но все равно это дерьмо может вылезти когда-нибудь еще.
56 user4fun
 
24.07.18
13:51
(55) (54) Спасибо!
57 H A D G E H O G s
 
24.07.18
13:52
Стапэ
58 H A D G E H O G s
 
24.07.18
13:52
(55) Эй, freeman, ну стопэ
59 H A D G E H O G s
 
24.07.18
13:53
Если мы сделаем запрос ДЛЯ ИЗМЕНЕНИЯ - мы тупо наложим U блокировку на Таб1 раньше, чем платформа наложит X блокировку на Таб2 в первой транзакции
60 H A D G E H O G s
 
24.07.18
13:54
Речь идет про 1 (пользовательскую, жертвенную) транзакцию.

Так, freeman ?
61 H A D G E H O G s
 
24.07.18
13:54
Этим мы изменим порядок захвата.
62 mr freeman
 
24.07.18
14:00
Тут не важно что будет U или S, мы не можем меняя тип управлять порядком их наложения. U это чисто для исключения s-s
63 H A D G E H O G s
 
24.07.18
14:04
(62) Почему не можем? Вот такая картина будет

1 транзакция: U Таб1 ждет, X Таб2 наложена, X Таб1 наложена (бывшая жертва)

2 транзакция: X Таб1 наложена, S Таб2 наложена
64 mr freeman
 
24.07.18
14:08
А как у тебя одновременно наложены X и S на Таб2?
65 H A D G E H O G s
 
24.07.18
14:11
(64) Никак.

U будет ждать X до конца транзакции 2 и наоборот.
66 mr freeman
 
24.07.18
14:11
И как можно одновременно наложить U и X в 1-й транзакции?
67 H A D G E H O G s
 
24.07.18
14:12
(66) Как угодно, бро. Как угодно.
68 mr freeman
 
24.07.18
14:14
(67) это для меня слишком сложно
69 H A D G E H O G s
 
24.07.18
14:16
(68) В рамках одной транзакции совместимы любые блокировки. Общего назначения уж точно, не скажу про всякие блокировки намеряний, не углублялся.
70 H A D G E H O G s
 
24.07.18
14:18
(68) За extended events system_health спасибо, кстати, какой бы ты злобной личностью бы не был. Я догадывался, что граф можно достать каким-нибудь dmv-ом, но как то руки не доходили, да и не особо нужно с управляемыми блокировками уже.
71 mr freeman
 
24.07.18
14:21
Совместимы в плане чего? Ты не можешь x превратить в u до окончания транзакции, так же как и u в s. Короче я не понимаю о чем ты, делай репро, выкладывай на ютуб, но я итак вижу что ты говоришь какие-то странные вещи.
72 H A D G E H O G s
 
24.07.18
14:22
(71) Просто забей.
73 H A D G E H O G s
 
24.07.18
14:27
(71) Вот, кстати, можешь почитать б-гмерской литературки.
https://its.1c.ru/db/metod8dev/content/4051/hdoc/_top/deadlock

Там в конце наш случай и мое решение, начиная со строк:
Для этого следует выполнить запрос с опцией "ДЛЯ ИЗМЕНЕНИЯ" к таблице остатков регистра "ТоварыКПередачеОрганизаций".

Переход по ссылке, ctrl+f, ctrl+v, enter
74 mr freeman
 
24.07.18
14:39
Ну я понял. В той транзакции где идет чтение изменений наложить U на справочник чтобы другая транзакция не могла менять  справочник и ожидала.
75 mr freeman
 
24.07.18
14:45
Т.е. блокировать все нужные ресурсы с самого начала транзакции. Классика жанра борьбы с дэдлоками если невозможен одинаковый порядок захвата.
76 H A D G E H O G s
 
24.07.18
14:47
(75) Да, именно.
77 mr freeman
 
24.07.18
15:19
(0) ТС попробуй перед записью характеристики блокировать таблицу регистрации изменений запросом в (23) но не в модуле объекта а перед ХарактеристикаНоменклатуры.Записать(), а все это безобразие нужно завернуть в транзакцию, начать ее перед запросом, зафиксировать после записи.
78 user4fun
 
25.07.18
06:35
(77) Благодарю.
79 H A D G E H O G s
 
25.07.18
11:06
За столбом гор фактов мы выплеснули ребенка.

Теперь, когда блокировка будет наложены и методологически все будет верно, юзер будет православно отваливаться по таймауту через 20 секунд, а не сразу и некошерно :-)

https://coub.com/view/16pe9l
80 mr freeman
 
25.07.18
11:20
(79) я сегодня подумал что U надо накладывать в обоих сеансах в начале транзакции, причем в одинаковом порядке на обе таблицы. Только в этом случае мы заставим 2-ю транзакцию, которая читает, ждать, т.к. U и S совместимы. Осталось только найти контекст виновника (контекст жертвы в ТЖ) и в обоих местах сделать это.
81 mr freeman
 
25.07.18
11:23
Т.к. U и S совместимы читать как нельзя оставлять S вообще.