Имя: Пароль:
 
1C
1С v8
Блокировки для обеспечения корректного отката транзакции
0 Demonius
 
24.03.17
16:14
Добрый день.
    Перепроводится документ РасходнаяНакладная с табличной частью Товары. Требуется контроль остатков. В новой версии документа в отличие от старой(ранее проведенной) есть некоторые новые позиции и ОТСУТСТВУЮТ некоторые старые позиции.
    Каким образом можно заблокировать эти старые позиции, чтобы была возможность откатить корректно транзакцию назад. Т.е., чтобы после отката гарантировать, что остатки по старым позициям будут неотрицательными.
    Заранее спасибо.
1 DrShad
 
24.03.17
16:17
что!?
2 Вафель
 
24.03.17
16:18
так вроде пока ты транзакция не завершил движения старых товров никуда не исчезают для других
3 Demonius
 
24.03.17
16:21
(2) При перепроводке очищаются старые позиции, которых нет в новой версии документа.  Если они (эти старые позиции) не будут заблокированы, то другая транзакция сможет провести расходную операцию.
4 DrShad
 
24.03.17
16:22
(3) не сможет
5 DrShad
 
24.03.17
16:22
только если ты не снял сначала проведение
6 Demonius
 
24.03.17
16:23
(3) Почему не сможет? Добавлю, что РегистрНакопления с разделением итогов.
7 DrShad
 
24.03.17
16:24
(6) потому что они никуда не деваются пока транзакция не завершена
8 Вафель
 
24.03.17
16:24
(7) отмена и проведение идут в одной транзакции
9 DrShad
 
24.03.17
16:25
(8) ну так а я о чем
10 Demonius
 
24.03.17
16:28
В старой версии РН:
Стол 1 шт.
Стул 1 шт.
Кровать 1 шт.

   До перепроведения в РН остатки:
Стол 0 шт.
Стул 0 шт.
Кровать 0 шт.
  
   В новой версии РН:
Стол 1 шт.
Стул 1 шт.

   Мне кажется, что при перепроведении запись в РН по Кровать очистится, но не заблокируется. После очистки другая транзакция может совершить расходную операцию.
11 Вафель
 
24.03.17
16:30
(10) Очитсится, но другие этого НЕ УВИДЯТ до конца транзакции
12 HardBall
 
24.03.17
16:30
(0) Надо блокировать все остатки по ТЧ товаров и все.
13 Demonius
 
24.03.17
16:31
(12)
Каким образом это сделать?
14 HardBall
 
24.03.17
16:33
15 Demonius
 
24.03.17
16:35
(14) Спасибо, но там про блокировки ничего нет.
16 HardBall
 
24.03.17
16:35
17 Вафель
 
24.03.17
16:37
(11) то бишь старые нельзя будет списать ибо транзакция еще не закрылась, а новые потому что ты из заблокируешь
18 Demonius
 
24.03.17
16:39
(17) Про новые понятно, что я их заблокирую. Почему старые система не позволит списать?
19 Вафель
 
24.03.17
16:39
(18) читай (11) до простветления
20 Demonius
 
24.03.17
16:40
(17) Почему старые (Кровать) будут заблокированы.
21 Demonius
 
24.03.17
16:41
(19) Я спрашиваю почему, ответ вроде
: "Очитсится, но другие этого НЕ УВИДЯТ до конца транзакции" не слишком информативен.
22 Вафель
 
24.03.17
16:42
(20) тебе нужно внимательно изучить тему про уровни изоляции
23 Вафель
 
24.03.17
16:42
(21) считай что другие будут думатьчто ты ничего не делаешь, для них документ в первоночальном состоянии
24 Demonius
 
24.03.17
16:45
(23) РН с разделением итогов!!!
25 Вафель
 
24.03.17
16:48
Ой все
26 Demonius
 
24.03.17
16:49
(23) Если РН без разделения итогов, то у меня вопросов нет. Я понимаю, что я могу указать Серверу 1с управляемую блокировку на коллекцию набора записей Движения.РН.БлокироватьДляИзменения. Но блокировка накладывается только на записи в коллекции. А в этой коллекции Кровать ОТСУТСТВУЕТ.
27 HardBall
 
24.03.17
16:49
(11) Не согласен. В управляемом режиме блокировок после очистки движений, остатки будут новые.
У Чистова так блокируется:
Если Режим = РежимПроведенияДокумента.Оперативный Тогда
  Движения.СтоимостьТоваров.Очистить();
  //17
  Движения.СтоимостьТоваров.БлокироватьДляИзменения = Истина;
  Движения.СтоимостьТоваров.Записать();
КонецЕсли;
28 Demonius
 
24.03.17
16:50
(23) при проведении в наборе записей новой версии документа будет только стол и стул.
29 Вафель
 
24.03.17
16:52
(27) а как же read commited?
30 Demonius
 
24.03.17
16:52
(27) Каким образом заблокируется запись Кровать? В данном случае, в коллекции набора записей только стол и стул.
31 Вафель
 
24.03.17
16:52
(27) код - это ваще полный п
32 Вафель
 
24.03.17
16:53
(30) скажи мне что такое разделение итогов?
33 HardBall
 
24.03.17
16:54
(31) Можно через блокировку. ;-)
34 Вафель
 
24.03.17
16:56
можешь эксперимент провести.
поставить точку останова после очистки двитжений. и при проведении другого выполнить запрос
35 Demonius
 
24.03.17
16:57
(32) при установленном в ИСТИНА свойстве РН "РазрешитьРазделениеИтогов", можно осуществять чтение и запись "параллельно" по одному и тому же набору измерений.
36 Вафель
 
24.03.17
16:57
(35) а каким образом достигается?
37 Demonius
 
24.03.17
16:59
(34) Я только учусь. Изучаю самостоятельно 1С. У меня не "клиент-сервер", поэтому блокируется вся таблица сразу. Не смогу проверить.
38 Demonius
 
24.03.17
16:59
(36) Добавляется новое "виртуальное" измерение.
39 Вафель
 
24.03.17
17:00
40 Demonius
 
24.03.17
17:05
(37) Другими словами, как мне наложить SERIARISABLE на записи со значением изменения Кровать?
SERIARISABLE я накладываю явно на Стол и Стул, посредством БлокироватьДляИзменения.
41 Demonius
 
24.03.17
17:07
(37) Я понимаю, что управляемые блокировки накладываются на уровне Сервера 1С на некоторые наборы записей.
42 Feanor
 
24.03.17
17:08
(41) ты зачем-то все в кучу смешал. В упр. режиме блокировок нет уровня изоляции "SERIARISABLE"
43 Demonius
 
24.03.17
17:08
БлокировтьДляИзменения - свойство набора записей, в котором отсутствует измерение со значением Кровать.
44 Demonius
 
24.03.17
17:09
(42) Нет. Согласен. Это понятие УРОВНЯ сервера БД.
45 Feanor
 
24.03.17
17:10
(44) Опять не так. В упр. режиме "SERIARISABLE" не используется
46 Demonius
 
24.03.17
17:13
(45) Я только учусь. Я не хотел лезть в эти дебри. Вопрос: что мне написать в коде, чтобы гарантированно другие транзакции не смогли читать/писать записи со значением измерения, равным "Кровать" до конца моей транзакции?
47 Demonius
 
24.03.17
17:18
Или поясните, какие записи блокирует т.н. запись "пустого набора записей" и до какого момента действует эта блокировка.
48 Feanor
 
24.03.17
17:19
(46) они и так не смогут, ничего особенного для этого делать не нужно.

В автоматическом режиме управления блокировками конфликт блокировок будет на запросе чтения остатков.

В управляемом режиме конфликт будет на установке управляемой блокировки перед запросом чтения остатков, которому насГать на разделитель итогов.
49 Feanor
 
24.03.17
17:22
+(48) Соответственно, в упр. режиме нужно установить управляемую блокировку. Явно или с помощью свойства "БлокироватьДляИзменения".
50 Demonius
 
24.03.17
17:25
(48) Вот. Управляемая блокировка устанавливается на набор записей. Верно?
     Но в наборе записей только "Стол" и "Стул". "Кровати" нет. (Кровать была в строй версии ранее проведенного документа). Соответственно вопрос, как наложить блокировку на "Кровать".
51 Feanor
 
24.03.17
17:27
(50) блокировку на "Кровать" накладывает вторая транзакция, которая эту самую кровать списывает. И как только она пытается ее установить - сразу же встает в ожидание, т.к. первая транзакция меняет остатки.
52 aleks_default
 
24.03.17
17:29
(51) Да, хоспади, если тебе так нужна эта кровать возьми ее из старых движений документа в начале обработки проведения(если режим удаления движений - "не удалять автоматически")
53 Feanor
 
24.03.17
17:32
(52) да не, вопрос на самом деле интересный товарищ сам себе задает
54 Demonius
 
24.03.17
17:33
(52) Я тоже об этом думал. Но там "Кровати" уже нет при перепроведении, к сожалению.
55 aleks_default
 
24.03.17
17:37
Посомтри как в типовых, например УНФ, сделан контроль остатков. Особенно модуль набора записей регистра накопления какого-нибудь типа Запаы
56 Garykom
 
24.03.17
17:38
(0) Решается очень просто...

Банальным запретом править (ТолькоПросмотр = Истина) проведенные документы.
57 Garykom
 
24.03.17
17:40
(56)+ нет "перепроведения" - нет проблемы ))
58 aleks_default
 
24.03.17
17:44
(56)Интерактивное изменение проведенных
59 Demonius
 
24.03.17
17:44
(55) Спасибо. Но я учусь самостоятельно. Нет возможности. Я хочу понять теоретически, что нужно сделать, чтобы не дать другим транзакциям возможности читать/записывать из/в РН записи в которых значение измерения ="Кровать".
Я должен что-то явно прописать или система это сделает неявно?
Повторю:
В старой версии РН:
Стол 1 шт.

Стул 1 шт.
Кровать 1 шт.

   До перепроведения в РН остатки:
Стол 0 шт.
Стул 0 шт.
Кровать 0 шт.
  
   В новой версии РН:
Стол 1 шт.
Стул 1 шт.

Если бы в новой версии РН было:
Стол 1 шт.
Стул 1 шт.
Кровать 0 шт.
   то вопроса бы не возникло, ибо я бы наложил управляемую блокировку: Движения.РН.БлокироватьДляИзменения.
60 Garykom
 
24.03.17
17:46
(58) Объясни нафуя? Проведение документа де факто = его подписанию с печатью.

Вы часто изменения в уже подписанные документы вносите? Или может дополнениями или старый того (отмена проведения) и составляем новый документ (и проводим)?
61 Demonius
 
24.03.17
17:46
(55) Т.е. я бы наложил управляемую блокировку на "Стол", "Стул", "Кровать". Однако, я накладываю только на "Стол" и "Стул" исключительную блокировку. Каким образом мне наложить исключительную блокировку на "Кровать"?
62 Garykom
 
24.03.17
17:47
(60)+ Ну объясните зачем сначала создавать себе трудности... а потом героически их преодолевать?
63 aleks_default
 
24.03.17
17:49
(60)Я говорю это право убрать, вместо всяких поделок типа ЭтаФорма.ТолькоПросмотр = Истина.
64 Demonius
 
24.03.17
17:50
(62) Ответьте конкретно: как наложить блокировку явно (программно) на "Кровать".
65 Feanor
 
24.03.17
17:55
66 Demonius
 
24.03.17
17:55
В ОбработкеПроведения():
...
Движения.РН.БлокироватьДляИзменения = Истина;
...
В коллекции Движения.РН есть только "Стол" и "Стул". "Кровать", которая была в строй версии документа и ранее была проведена отсутствует в коллекции Движения.РН.
Значит, она не блокируется?
67 Demonius
 
24.03.17
17:58
(64) Да читал я очень много по подобным ссылкам. На этот форум пришел с последней надеждой, к практикам с опытом, так сказать. Но здесь конкретного ответа тоже не нашел, к сожалению :(
68 aleks_default
 
24.03.17
17:58
Домой иди уже...
69 bolobol
 
24.03.17
18:02
Вас троллят, господа.
70 Demonius
 
24.03.17
18:04
(69) Господа ответить не смогли предметно, к сожалению.
71 Feanor
 
24.03.17
18:09
(70) чем тебя ответ в (51) не устроил? :)
72 Demonius
 
24.03.17
18:22
(71) (50) блокировку на "Кровать" накладывает вторая транзакция, которая эту самую кровать списывает. И как только она пытается ее установить - сразу же встает в ожидание, т.к. первая транзакция меняет остатки.

Если следовать логике того, что написано выше, тогда конструкция  БлокироватьДляИзменения не требуется, ибо первая транзакция меняет остатки не только по "Кровать", но и по "Стол", "Стул". По вышеописанной логике вторая транзакция не сможет работать с этими записями.
73 Garykom
 
24.03.17
18:31
(63) К сожалению права (в 1С) разные недоадмины навострились править, а вот в код они обычно не лезут.
74 bolobol
 
24.03.17
18:32
(72) Так вопрос в (0) же другой был!
75 Feanor
 
24.03.17
18:50
(72) С фигали БлокироватьДляИзменения не требуется? У тебя в документе может быть только кровать, никаких столов и стульев. Мысль в том, что блокировка защищает данные и не дает другим транзакциям создавать некорректные ситуации, например, списывать в минус.
76 ГеннадийУО
 
24.03.17
18:51
(72) БлокироватьДляИзменения отключит разделение итогов на время транзакции.
77 Feanor
 
24.03.17
18:54
(76) БлокироватьДляИзменения не отключит разделение итогов (удалит колонку из таблицы в БД что ли?), а наложит управляемую блокировку, только и всего. Разделитель в управляемых блокировках не используется.
78 h-sp
 
24.03.17
21:22
(0) что-то вы чудите, и другие повелись. Если логически подумать, то остатки никогда не будут отрицательными. Рассмотрите все варианты, убедитесь сами.
79 kev789
 
24.03.17
21:38
(72)
RPC:Completed    exec sp_executesql N'SELECT
T1._Period,
T1._RecorderTRef,
T1._RecorderRRef,
T1._LineNo,
T1._Active,
T1._RecordKind,
T1._Fld127RRef,
T1._Fld128
FROM dbo._AccumRg126 T1
WHERE T1._RecorderTRef = 0x000000AA AND T1._RecorderRRef = P1
ORDER BY T1._LineNo',N'P1 varbinary(16)',0xBFFE002522A6B98411E710BEA55D2788    1CV83 Server        sa    0    6    0    0    3652    51    2017-03-24 21:26:05.817    2017-03-24 21:26:05.817    0X00000000040000001A00730070005F006500780065006300750074006500730071006C00E001000082000A0063206E007400650078007400C8010000530045004C004500430054000A00540031002E005F0050006500720069006F0064002C000A00540031002E005F005200650063006F00720064006500720054005200650066002C000A00540031002E005F005200650063006F007200    
RPC:Completed    exec sp_executesql N'DELETE FROM T1
FROM dbo._AccumRg126 T1
WHERE T1._RecorderTRef = 0x000000AA AND T1._RecorderRRef = P1 AND ((T1._LineNo = @P2) OR (T1._LineNo = @P3))',N'P1 varbinary(16),@P2 numeric(10),@P3 numeric(10)',0xBFFE002522A6B98411E710BEA55D2788,1,2    1CV83 Server        sa    0    20    0    0    3652    51    2017-03-24 21:26:05.817    2017-03-24 21:26:05.817    0X00000000060000001A00730070005F006500780065006300750074006500730071006C004001000082000A0063206E00740065007800740028010000440045004C004500540045002000460052004F004D002000540031000A00460052004F004D002000640062006F002E005F0041006300630075006D00520067003100320036002000540031000A005700480045005200450020005400
80 kev789
 
24.03.17
21:40
(79)+
(72) Как я понял, платформа, перед записью новых движений, удаляет старые(что логично), Но перед этим считывает их. Думаю что в этот момент и устанавливает блокировку на сервере 1С
81 kev789
 
24.03.17
21:43
(80) +
режим совместимости 8.3.8 управляемые блокировки
обработка проведения расходной простейшая:

Процедура ОбработкаПроведения(Отказ, Режим)
    //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

    // регистр Товары Приход
    
    Движения.Товары.Записывать = Истина;
    Движения.Товары.БлокироватьДляИзменения = Истина;
    
    Для Каждого ТекСтрокаТовары Из Товары Цикл
        Движение = Движения.Товары.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
        Движение.Количество = ТекСтрокаТовары.Количество;
    КонецЦикла;

    
    //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    
    Движения.Записать();
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
                   |    ТоварыОстатки.Номенклатура,
                   |    ТоварыОстатки.КоличествоОстаток КАК Остаток
                   |ИЗ
                   |    РегистрНакопления.Товары.Остатки(
                   |            ,
                   |            Номенклатура В
                   |                (ВЫБРАТЬ
                   |                    ДокТЧ.Номенклатура
                   |                ИЗ
                   |                    документ.расходная.Товары КАК ДокТЧ
                   |                ГДЕ
                   |                    ДокТЧ.Ссылка = &Ссылка)) КАК ТоварыОстатки
                   |ГДЕ
                   |    ТоварыОстатки.КоличествоОстаток < 0";

    Запрос.УстановитьПараметр("Ссылка",Ссылка);
    РезультатЗапроса = Запрос.Выполнить();
    Отказ = Не РезультатЗапроса.Пустой();
    Если Отказ Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Пока Выборка.Следующий() Цикл
            Сообщить(Выборка.Номенклатура);
            Сообщить(    "        " + Выборка.Остаток);
            
        КонецЦикла;
    КонецЕсли;    
КонецПроцедуры