Имя: Пароль:
1C
1С v8
Блокировка записи РС
,
0 Sasha_H
 
18.07.12
14:09
Всем привет.

Вопрос собственно вот в чем.
В РС.Объекты_ID имееются только два числовых ресурса (Ч10) "DocID" и "DocRecID"

Принцип работы "синхрофазатрона" (этот РС необходим для обмена в другую не 1С БД, где используют ключи), а именно перед записью документа хочу получить эти числа и ес-но сделать +1.

Так вот вопрос, а именно интересует блокировка, я хочу сделать примерно так:

ПередЗаписью()

Запись = РС.Объекты_ID.Прочитать();
Запись.Получить();
перемDocID = Запись.DocID; (эту переменную присвою в реквизит шапки документа)

Потом создаю наборЗаписи.РС.Объекты_ID и туды пишу Запись.DocID+1.
и наборЗаписи.Записать();

Интересует момент блокировок, при таком чтении и записи кто-то сможет считать неуникальные данные.

Можно пробовать и считать записи с рега и запросом дляИзменения.

просто момент в том, чтобы прочитать уникальное число проставить в его в реквизит документа и записать сразу же в РС новое число.

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

PS/ к деталям кода просьба недомахиватся так как это просто наброска чего хочу сделать...
1 Sasha_H
 
18.07.12
16:59
жесть как много ответов!
2 Ненавижу 1С
 
гуру
18.07.12
17:00
на тормоза наплевать?
тогда делай в транзакции
читай данные запросом с ключом ДЛЯ ИЗМЕНЕНИЯ
3 MadHead
 
18.07.12
17:06
В документации все написано. В момент записи документа начинается неявная транзакция начиная с обработчика "Перед записью" и заканчивая окончанием записи или откатом транзакции. На все данные считанные в запросе накладывается блокировка на запись (для регистра будет накладываться в разрезе наборов измерений). Если используешь для изменения то блокировка накладывается и на чтение. Блокировка снимается по окончанию транзакции. Задумка так себе читать подобный регистр в транзакции, я бы советовал генерить ГУИД
4 х86
 
18.07.12
17:17
(0)для получения уникального номера используй справочник
5 Sasha_H
 
18.07.12
17:29
Дело в том, что нужно только число!
6 Sasha_H
 
18.07.12
17:33
Измерений не использую, только два ресурса в котром содержатся последние ИД шапки и строк
7 х86
 
18.07.12
17:34
(5)в справочнике код может быть числовым
8 Sasha_H
 
18.07.12
17:39
(7) справочник медленный для этого дела!
9 х86
 
18.07.12
17:42
(8)не на много медленне РС, а с учетом >>Можно пробовать и считать записи с рега и запросом дляИзменения  так вообще всё будет шеколадно
10 Sasha_H
 
18.07.12
17:44
Вот что-то такое наварганил на подписке на события "ПередЗаписью"

Процедура ПередЗаписьюДокументаДляОбменаЛЦ(ДокументОбъект,Отказ) Экспорт
   
   МетаданныеДокумента = ДокументОбъект.Метаданные();
   
   Если НЕ ОбщегоНазначения.ЕстьРеквизитДокумента("DocID", МетаданныеДокумента)
       или Не ОбщегоНазначения.ЕстьТабЧастьДокумента("Товары",МетаданныеДокумента) Тогда
       Возврат;
   КонецЕсли;    
   
   Отбор = Новый Структура("DocRecID",0);
   Товары = ДокументОбъект.Товары;
   
   СтрокиДокумента = Товары.НайтиСтроки(Отбор);
   
   Если ЗначениеЗаполнено(ДокументОбъект.DocID) и СтрокиДокумента.Количество()=0 Тогда
       Возврат; //Всем строкам и шапке документа ID присвоенно
   КонецЕсли;    
   
   Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ
   |    Объекты_ID.DocID,
   |    Объекты_ID.DocRecID
   |ИЗ
   |    РегистрСведений.Объекты_ID КАК Объекты_ID
   |
   |ДЛЯ ИЗМЕНЕНИЯ
   |    РегистрСведений.Объекты_ID");
   
   РезЗапр = Запрос.Выполнить();
   Выборка = РезЗапр.Выбрать();
   Выборка.Следующий();
   
   Если РезЗапр.Пустой() Тогда
       Возврат;
   КонецЕсли;    
   
   мDocID        = Выборка.DocID;
   мDocRecID    = Выборка.DocRecID;
   
   //Записуем данные в РС
   НаборЗаписей = РегистрыСведений.Объекты_ID.СоздатьНаборЗаписей();
   
   НоваяЗапись = НаборЗаписей.Добавить();
   НоваяЗапись.DocID        = ?(ЗначениеЗаполнено(ДокументОбъект.DocID), мDocID,мDocID+1);
   НоваяЗапись.DocRecID    = ?(СтрокиДокумента.Количество()=0,мDocRecID, мDocRecID+СтрокиДокумента.Количество());
   
   НаборЗаписей.Записать();
   
   //Проставляем реквизиты в документ
   Если Не ЗначениеЗаполнено(ДокументОбъект.DocID) Тогда
       ДокументОбъект.DocID = мDocID+1;
   КонецЕсли;    
   
   Для каждого СтрокаТабличнойЧасти Из СтрокиДокумента Цикл
       
       СтрокаТабличнойЧасти.DocRecID = мDocRecID + 1;
       мDocRecID = мDocRecID+1;
       
   КонецЦикла;    
   
КонецПроцедуры
11 Infsams654
 
18.07.12
17:59
(10) - не прокатит. Одновременно прочитали РС и хотят  записать ид + 1. Если делать блокировку на чтение, то с блокировками тормоза будут. (3) советует генерить гуид. Сделай функцию ПолучитьЧисло(ГУИД)
12 hhhh
 
18.07.12
18:06
(10) надо использовать НаборЗаписей.Отбор
А то она вам весь регистр полностью сотрет.
13 Sasha_H
 
18.07.12
18:07
(12) У меня ресурсы только,  измерений нету. я просто перезаписую данные если необходимо!
14 hhhh
 
18.07.12
18:07
(12) тьфу, у вас тут всегда одна запись, извиняюсь.
15 Sasha_H
 
18.07.12
18:08
эм... тут бы надо бы управляемую блокировку но я сней не работал. Интересует момент  наложить блокировку вовремя прочтения и записи и отпустить ее.
16 Sasha_H
 
18.07.12
18:09
насколько я понимаю на данный момент таблица РС будет заблокирована пока транзакция  записи документа полностью не закончится?
17 Sasha_H
 
18.07.12
18:11
хотя версию как пилотную думаю можно запустить :)
18 vde69
 
18.07.12
18:18
во первых не одязательно вообще что-то генерить или считывать, уде есть ГУИД документа

во вторых если все-же хочется иметь именно числовой ID по порядку то делается это так

ID - измерение РС и обязательно ОДНО

код:

LastID = ПолучитьПоследнийID(); // способ получения не имеет значение
попытка
 начатьтранзакцию()
   Запрос = новый запрос()
   запрос.текст = "выбрать * первые 1 для изменения из рег где рег.ID = &пар"
   запрос.установитьпараметр("пар", LastID )
   р = запрос.выполнить()
   // здесь мы заблокировали предположительно последнюю запись
   // переменные р и запрос нельзя трогать до конца транзкции
   newID = lastID+1;
   // здесь любым способом проверим что нового ид нет в регистре
   .......
   //здесь записываем в регист новую строку и делаем все что нужно в документе
   ......
 зафиксироватьтранзакцию()
исключение
// если попали сюда то или ошибка записи или блокировки
отменитьтранзакцию()
отказ=ичтина
конецпопытки
19 vde69
 
18.07.12
18:19
(18) писал с листа, наверно есть ошибки
20 Sasha_H
 
18.07.12
18:20
а вчем разница в данном случае?
21 Sasha_H
 
18.07.12
18:21
в моем случае необходимо два ИД, для строк и для Шапки
22 Sasha_H
 
18.07.12
18:21
а РС в ресурсах и хранит последний числовой ИД шапки и строки табличной части.
23 Sasha_H
 
18.07.12
18:22
использовать измерения вообще не вижу смысла, так как достаточно просто прочитать РС для получения данных значений и установить новые.
24 vde69
 
18.07.12
18:26
(23) запись в регистре можно заблокировать ТОЛЬКО по ключу, ключ это набор измерений (в том числе предопределенных), без измерения будет блокироватся ВЕСЬ регист.

без блокировки словишь одинаковые ИД.
25 hhhh
 
18.07.12
18:29
(24) да у него в регистре одна запись. По-любому получается весь регистр. Он так и планирует.
26 vde69
 
18.07.12
18:34
(25) у него ДВА поля "DocID" и "DocRecID" значит у него регистр содержит связь между ними, в противном случае можно юзать константу
27 Sasha_H
 
18.07.12
18:47
(26) два поля но запись одна!!!
28 Sasha_H
 
18.07.12
18:47
так что запись одна пусть блокируется весь регистр меня это вполне устраивает
29 vde69
 
18.07.12
18:54
(28) ппц... ушел читать фантастику
30 Sasha_H
 
18.07.12
19:00
а в чем то шок? Константа не канает так как при записи блокируется весь набор констант, а их там значительно много.

Только РС и в данной форме он вполне нужен
31 Sasha_H
 
18.07.12
19:01
Даже готов поспорить, что с измерением в случае который нужен мне на определенные долесекунды будет дольше.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.