|
Управляемые блокировки, помогите разобраться | ☑ | ||
---|---|---|---|---|
0
Ululg
26.12.11
✎
14:48
|
База на SQL. В справочник добавил новый реквизит и он должен быть уникальным. Но по факту получается все очень печально, т.к. если одновременно пользователи записывают в справочник данные - реквизит начинает задваивается. Как по-хитрому наложить блокировку, чтобы заблокировать таблицу с пустыми номерами? Или подскажите какой-нибудь оптимальный алгоритм для задания своего рода уникального идентификатора?
|
|||
1
vmv
26.12.11
✎
15:07
|
Объект = ТекущийОбъект.ПолучитьОбъект();
ЗаблокироватьДанныеДляРедактирования(Объект.Ссылка); Если ПроверкуУникальностиПрошел(Объект) Тогда ДелоОбъект.Записать(); КонецЕсли; Можешь на ГУИД проверять и реквизит, если он ссылочный Функция ОбъектУникальныйИдентификатор() //... //... Возврат Истина; КонецФункции; |
|||
2
shuhard
26.12.11
✎
15:10
|
(1) + 1
я бы попытку добавил перед ЗаблокироватьДанныеДляРедактирования(Объект.Ссылка); и счетчик какой нибудь попыток |
|||
3
Ululg
26.12.11
✎
15:11
|
Дело в том, что мне надо блокировать всю таблицу видимо, потому что реквизит надо заполнить по схеме - МАКСИМУМ+1. И при одновременной записи 2 разных элементов им раздается одинаковый код, потому что максимум они одинаковый отобрали в запросе(
|
|||
4
Ululg
26.12.11
✎
15:12
|
и если вот так:
Если ПроверкуУникальностиПрошел(Объект) Тогда ДелоОбъект.Записать(); КонецЕсли; то оба элемента пройдут уникальность - косяки будут только после записи. |
|||
5
Живой Ископаемый
26.12.11
✎
15:12
|
Почитайте про транзакцию и предложение запроса "для изменения" в Ф1
|
|||
6
Ululg
26.12.11
✎
15:14
|
у меня база на управляемых блокировках) не помогает в запросе галочка для изменения - уже все это пройденный этап
|
|||
7
DmitrO
26.12.11
✎
15:16
|
(5)казалось бы, причем тут управляемые блокировки :)
|
|||
8
Живой Ископаемый
26.12.11
✎
15:17
|
м... а как там работает?
в Ф1 написано что Предложение ДЛЯ ИЗМЕНЕНИЯ предназначено для указания необходимости блокировки считываемых в транзакции данных. Считанные данные становятся недоступными для чтения в других сессиях. Для файлового варианта блокируются указанные таблицы, а для клиент-серверного варианта — только выбранные записи. Блокировка снимается после завершения транзакции. Я могу ошибаться но транзакиця начинается когда? В передзаписью? а заканчивается? Если в запросе не будет условий - будет блокироваться вся таблица? или если блокировки управляемые, то предложение по боку? |
|||
9
Dmitrii
гуру
26.12.11
✎
15:28
|
(8) >> если блокировки управляемые, то предложение по боку?
- Да. |
|||
10
vmv
26.12.11
✎
15:41
|
уточним, несколько юзеров пишут объекты справочника1 в которых реквизит данных этого справочника ,допустим, "Вид" иммет тип Справочник2
Условия: в Справочнике1 не должно быть элементов с одиноквым реквизитом "Вид" и запись происходит единовременно. Т.е. вид по сути выполняет роль второго гуида Справочник1 Очевидно, что когда несколько юзеров пишут справочник1, то блокировать нужно и ссылку реквизита Вид, таким образом дубли не пройдут и после записи справочника1 в ссылку "Вид"(Справочника2) тоже что-то писать или не писать. потом разблокировать оба, как-то так) |
|||
11
Axel2009
26.12.11
✎
15:44
|
запись в скуль одинаковых данных можно предугадать только уникальным индексом. уникальный индекс создается только по РС по измерениям.
|
|||
12
Господин ПЖ
26.12.11
✎
15:50
|
(5) бугага...
|
|||
13
milan
26.12.11
✎
15:50
|
(0) Скоростные у тебя пользователи, имхо не вовремя ты реквизит справочника заполняешь.
Ну а что насичет объекта "Блокировак данных" ? |
|||
14
DmitrO
26.12.11
✎
16:02
|
(10) ты вот тут телепатируешь или действительно имеешь какое-то отношение к ТС, или вообще свою задачу решаешь?
|
|||
15
Ululg
26.12.11
✎
16:11
|
(13) вот я его и использую, только не могу понять когда правильно заблокировать данные для изменения
Блокировку устанавливаю. но все равно задвоенные есть |
|||
16
DmitrO
26.12.11
✎
16:14
|
У меня впечатление, что почти никто до конца не понимает механизма блокировок, но все говорят что автоматические это пройденный этап и я хочу это проверить.
Если до 17:00 никто не запостит решение, тогда его запостю я. |
|||
17
Axel2009
26.12.11
✎
16:44
|
(16) 100% решение для автоматических блокировок без уникального регистра?
|
|||
18
Feanor
26.12.11
✎
17:02
|
17:02...
|
|||
19
vmv
26.12.11
✎
17:15
|
Пример
Допустим, Справочник.СтруктураПредприятия изначально пуст, далее Ссылка допустим рукводитель может руководить только одним подразделением два юзера одновременно пишут Контрагента с набором полей Наименование: "АУП" Руководитель: Иванова И.И. (Справоччик чего-то там) 1. Проверяем на уникальность связанныую пару Ссылка(ГУИД Струткура предприятия и руководитель) 2. Проверяем на блокировку Руководитель 3. Если не блокирова, то блокируем сначала Руководитель потом Ссылка 4. Записываем/перезаписываем Ссылка 5. Разблокируем сначала Ссылка потом Руковдитель не взлетит? |
|||
20
Ululg
26.12.11
✎
18:08
|
неа, у меня пользователи могут выбрать максимум и к нему +1 сделать, даже если я ставлю Исключительный режим :(
|
|||
21
milan
26.12.11
✎
19:17
|
(16) Жаль что так и не удалось услышать начальника транспортного цеха.
|
|||
22
Господин ПЖ
26.12.11
✎
19:21
|
>допустим рукводитель может руководить только одним подразделением
почему мощность связи нельзя регулировать структурой регистра сведений... |
|||
23
vmv
26.12.11
✎
19:25
|
(22) пример упрощенный и взят наобум
моджно, конечно. пример Связи документов в Документооборот 8, но ведь тогда нужно будет следить и за регистром, а если учетная система проста и выделена под конкретную задачу, буквально один док и пара справочников, то зачем пускат козла(регистр) в огород) |
|||
24
Господин ПЖ
26.12.11
✎
19:26
|
а зачем делать не работающую хню из (19)?
|
|||
25
vmv
26.12.11
✎
19:29
|
(24) там есть ключевые слова Допустим и я не спец по управляемым блокам, что с того, что позволил себе пару допущений в надежде, что такой зубро как вы разложит все по полкам и выложит действительно правильный и надежный код и идею)
|
|||
26
Господин ПЖ
26.12.11
✎
19:33
|
>У меня впечатление, что почти никто до конца не понимает механизма блокировок
понимать как раз можно механизм автоблокировок... ибо блокируется средствами скуля и по этой теме много инфы... а что происходит при упр. блокировках на самом деле - знает один Нуралиев |
|||
27
vmv
26.12.11
✎
19:36
|
(26) это действительно так, все привыкли на них не обращать внимание, сейчас прийдется с ними работать
|
|||
28
vmv
26.12.11
✎
19:39
|
(26) Мануал от указанного вами господина
ЗаблокироватьДанныеДляРедактирования(<Ключ>, <ВерсияДанных>, <ИдентификаторФормы>) Заблокировать данные для редактирования в управляемой форме. Вызывает исключение, если объект уже заблокирован, в том числе и методом Заблокировать. Все четко, понятно, лаконично, но что происходит действительно загадка) |
|||
29
Живой Ископаемый
26.12.11
✎
19:40
|
2(28) это тоже к управляемым блокировкам не имеет отношения.
|
|||
30
DmitrO
26.12.11
✎
19:45
|
Сразу после 17:00 запостить не удалось, т.к. нас сегодня выгнали из офиса немного раньше по техническим причинам, а потом я уехал по делам.
На сколько я понял, задача состоит в заполнении некоторого реквизита справочника, уникальным значением при записи. Уникальность значения допустимо обеспечивать простым инкрементом максимального значения. Для упрощения, будем считать, что тип реквизита Число. Обещанное решение. На управляемых блокировках. Считаем что объект записывается в управляемой транзакции. В событии объекта ПередЗаписью: Если МойРеквизит=0 Тогда //Значение МойРеквизит не назначено, назначим же его //В данном случае блокировать можно любую ссылку, лишь бы все клиенты блокировали одно и тоже //на эту роль отлично подходит пустая ссылка Блокировка = Новый БлокировкаДанных; Элемент = Блокировка.Добавить("Справочник.МойСправочник"); Элемент.Режим = РежимБлокировкиДанных.Исключительный; Элемент.УстановитьЗначение("Ссылка", Справочники.МойСправочник.ПустаяСсылка()); Блокировка.Заблокировать(); //ожидание блокировки будет здесь //теперь я работаю всегда только один, остальные курят Запрос = Новый Запрос("выбрать ЕстьNull(Максимум(МойРеквизит), 0) как МаксимальноеЗначение из Справочник.МойСправочник"); Выб = Запрос.Выполнить().Выбрать(); Выб.Следующий(); МойРеквизит = Выб.МаксимальноеЗначение + 1; Иначе //Значение МойРеквизит назначено, проконтролируем уникальность //.... КонецЕсли; На автоматических блокировках. Считаем что объект записывается в автоматической транзакции. В событии объекта ПередЗаписью: Если МойРеквизит=0 Тогда //Значение МойРеквизит не назначено, назначим же его Запрос = Новый Запрос("выбрать ЕстьNull(Максимум(МойРеквизит), 0) как МаксимальноеЗначение из Справочник.МойСправочник для изменения"); Выб = Запрос.Выполнить().Выбрать(); //ожидание блокировки будет здесь //теперь я работаю всегда только один, остальные курят Выб.Следующий(); МойРеквизит = Выб.МаксимальноеЗначение + 1; Иначе //Значение МойРеквизит назначено, проконтролируем уникальность //.... КонецЕсли; |
|||
31
Zolotko
27.12.11
✎
12:48
|
(30) А если надо старым элементам задать уникальные значения?
|
|||
32
pumbaEO
27.12.11
✎
12:58
|
(31) обработкой пройтись в монопольном режиме.
|
|||
33
Zolotko
27.12.11
✎
13:02
|
(33) 3 миллиона записей? не вариант :(
|
|||
34
Живой Ископаемый
27.12.11
✎
13:03
|
2(33) там же написано - передзаписью... проходишь, записываешь.
|
|||
35
Zolotko
27.12.11
✎
13:20
|
(34) "...в монопольном режиме..."
|
|||
36
Живой Ископаемый
27.12.11
✎
13:24
|
2(35) не делайте в монопольном.
|
|||
37
Zolotko
27.12.11
✎
13:26
|
(36) короче забей
|
|||
38
Живой Ископаемый
27.12.11
✎
13:27
|
ок, как скажите, забил
|
|||
39
DmitrO
27.12.11
✎
14:05
|
(31)Для этого достаточно пройтись по этим объектам обработкой. Для каждого объекта надо очистить значение реквизита и записать объект. Монопольный режим конечно же вовсе не обязателен, у нас же есть блокировки.
|
|||
40
DmitrO
27.12.11
✎
14:16
|
(33)если нужно обработать много записей, тогда для управляемых транзакций для ускорения процесса так:
1.начинаем управляемую транзакцию 2.точно также блокируем как в (30) 3.для каждого элемента в цикле: ТекущееЗначение = ТекущееЗначение+1; Объект.ОбменДанными.Загрузка = Истина; Объект.МойРеквизит = ТекущееЗначение; Объект.Записать(); 4.Фиксируем транзакцию Монопольный режим, опять же, не обязателен. |
|||
41
Ululg
29.12.11
✎
14:49
|
У меня все равно не блокируется, лиобо блокируется, но код тотже присваивается. Подскажите где ошибка, плиз:
Если Не ЗначениеЗаполнено(КодДляНС) Тогда Если ЭтоГруппа Тогда КодДляНС= НайтиПоследнийКодСУчетовВидаДоговора("L"); Иначе Если КредитныйДоговор Тогда КодДляНС= НайтиПоследнийКодСУчетовВидаДоговора("K"); Иначе КодДляSAP = НайтиПоследнийКодСУчетовВидаДоговора("L"); КонецЕсли; КонецЕсли; КонецЕсли; Функция НайтиПоследнийКодСУчетовВидаДоговора(Префикс) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДоговорыКонтрагентов.Ссылка |ИЗ | Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов |ГДЕ | ДоговорыКонтрагентов.КодДляНС= &КодДляНС | |ДЛЯ ИЗМЕНЕНИЯ | Справочник.ДоговорыКонтрагентов"; Запрос.УстановитьПараметр("КодДляНС", ""); Результат = Запрос.Выполнить(); БлокировкаДанных = Новый БлокировкаДанных; ЭлементБлокировки = БлокировкаДанных.Добавить("Справочник.ДоговорыКонтрагентов"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; ЭлементБлокировки.УстановитьЗначение("Ссылка", Справочники.ДоговорыКонтрагентов.ПустаяСсылка()); БлокировкаДанных.Заблокировать(); НовыйКод = ""; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | МАКСИМУМ(ДоговорыКонтрагентов.КодДляНС) КАК КодДляНС |ИЗ | Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов |ГДЕ | ДоговорыКонтрагентов.КодДляНС ПОДОБНО &Префикс"; Запрос.УстановитьПараметр("Префикс", Префикс+"%"); Результат = Запрос.Выполнить().Выбрать(); Если Результат.Следующий() Тогда Если Результат.КодДляНС<> NULL Тогда НовыйКод = Префикс+Формат((Число(Сред(Результат.КодДляНС,2, 13)) + 1), "ЧЦ=12; ЧВН=; ЧГ=0"); Иначе НовыйКод = Префикс + "000000000001"; КонецЕсли; Иначе НовыйКод = Префикс + "000000000001"; КонецЕсли; Возврат НовыйКод; КонецФункции |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |