Имя: Пароль:
1C
1С v8
Блокировка таблицы изменений. Как?
,
0 bolobol
 
18.10.13
16:45
Приветствую!

Что-то никак мне не решить задачку:
Есть план обмена в котором регаются изменения по регистру сведений.
Периодически, запросом по таблице изменений выгружаю данные насторону.
Пока выгружаю, новая партия данных поступает в рег и к выполнению команды ПланыОбмена.УдалитьРегистрациюИзменений(Узел) - удаляются и те изменения, что я выгрузил и те, что во время выгрузки появились новые.
У меня SQL, блокировки по записям.

Делал:
НачатьТранзакцию();
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.ЗначенияНаВыгрузку");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();

- бесполезняк, данные добавляются, таблица изменений наполняется

Делал 2:
НачатьТранзакцию();
Запрос... Выбрать МАКСИМУМ(ЗначенияНаВыгрузкуИзменения.НомерСообщения) ДЛЯ ИЗМЕНЕНИЯ

- но толку тоже никакого - данные _добавляются_ - таблица изменений наполняется

Как же заблочить всю таблицу Изменений или весь РегистрСведений, шоб аж добавить ничего нельзя было до конца транзакции?
1 Maxus43
 
18.10.13
16:48
>>Периодически, запросом по таблице изменений выгружаю данные насторону.
что мешает делать классически, не изобретая велосипеды?
2 bolobol
 
18.10.13
16:50
(1) Что в вашем понимании "классически"?
3 Maxus43
 
18.10.13
16:51
(2) ВыбратьИзменения и т.д., проставляется номер сообщения, удаление регистрации происходит по номеру сообщения а не всё что там есть, короче стандартно
4 bolobol
 
18.10.13
17:01
(3) Номер сообщения всегда 0. Удаляя по номеру сообщения 0 - удаляются также все записи. И те что добавились за время выгрузки - тоже. А как заставить план обмена генерить номера сообщений не НОЛЬ - не ясно, кстати, ещё актуальный вопрос.
5 Maxus43
 
18.10.13
17:08
узел то не один хоть?

                // Создаем новое сообщение
                ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

                ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена);
                
                // для РИБ изменения в информационной базе
                ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения, СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных);
                
                // Завершаем запись сообщения
                ЗаписьСообщения.ЗакончитьЗапись();
                    
                ЗаписьXML.Закрыть();
6 Maxus43
 
18.10.13
17:08
будет XML со всеми данными зарегистрированными и с проставленными номерами
7 bolobol
 
18.10.13
17:11
(5) Икс... Узелов два... две... двое))
Но причём здесь хмл? Без него (не создав его) нельзя корректно пользоваться планом? С какой стороны курить-то это?
8 Maxus43
 
18.10.13
17:14
(7) ну курить надо хотя бы проф разработку, главу по планам обмена, раз вобще не в зуб ногой)
9 bolobol
 
18.10.13
17:25
(8) Ну, это не ответ))
А по сути вопроса? План обмена есть, изменения заполняются. А выбрать изменения на текущий момент, так чтоб их отрегить от плана - никак что ли?
10 SUA
 
18.10.13
17:31
1) ПланыОбмена.ВыбратьИзменения() с нумерацией сообщений
или
2) Фоновый (2й) узел обмена -
начало обмена -> запросом выбрать изменения из 1го, перенести во 2й, удалить из 1го -> обменяться со 2м узлом (с удалением регистрации при успешном обмене оттуда)
11 SUA
 
18.10.13
17:31
при этом удалять регистрацию пообъектно можно
12 hhhh
 
18.10.13
17:32
(9) выкинуть ПланыОбмена.УдалитьРегистрациюИзменений(Узел)

удалять регистрацию по каждому объекту.
13 bolobol
 
18.10.13
17:37
(10) 1) - изменения выбираются, и пока я этот список отправляю, в таблице изменений появляются ещё изменения, которые тоже с номером НОЛЬ! Под конец, удаление по номеру НОЛЬ - очищает _всю_ таблицу изменений.
2) Здесь не понял, чем это отличается от 1 - пока перегружаю, так там всего понадобавляется...

(11) (12) Пообъектно регистрацию не удалить, т.к. пока я выгружаю один этот объект и перехожу к строке - удалить из изменений этот объект = пользователь снова может записать изменение этого объекта! И, получается, выгрузил я старую запись, а регистрацию удалил и по обновлённому.

Вот где собака порылась!
14 hhhh
 
18.10.13
17:44
(13) ну это уже вероятность 0,0005%. Наэто можно спокойно забить.
15 Maxus43
 
18.10.13
17:44
Для этого и сделан механизм НУМЕРАЦИИ сообщений, чтоб были согласованные данные, я не понимаю о чем тут речь господа, всё написано давно и давно реализовано во всех типовых и так далее
16 bolobol
 
18.10.13
17:51
(14) Данная вероятность в день отрабатывает на 30%. Забить != правильно. А надобно именно правильно и максимально прозрачно.

(15) Что с этим механизмом? Изменения регистрируются платформой, а увеличить с определённого момента номер сообщения-то как платформу заставить? Отсюда и речи, что ответа нет, а вопрос есть! И в типовых механизмах ежедневно приходится по одному-двум объектам повторно регать изменения - вот и думаю, не косяк ли там тот же закрался(?)
17 Maxus43
 
18.10.13
18:05
>>И в типовых механизмах ежедневно приходится по одному-двум объектам повторно регать изменения
что за ересь то?
>>Изменения регистрируются платформой, а увеличить с определённого момента номер сообщения-то как платформу заставить?

Синтаксис:

ВыбратьИзменения(<Узел>, <НомерСообщения>, <ФильтрВыборки>)

Описание:

Формирует выборку измененные данные для передачи их в тот или иной узел плана обмена. При этом в процессе выборки изменений в записи регистрации изменений проставляется номер сообщения обмена данными, в котором должны передаваться изменения. Номер сообщения в записи регистрации проставляется для того, чтобы при подтверждении приема сообщения, в котором передавались изменения соответствующие записи регистрации изменений были удалены и в дальнейшем изменения больше не передавались.
18 Maxus43
 
18.10.13
18:08
(17) + номер проставится только у тех, которые на данный момент будут в Выборке.
Если в процессе кто-то запишет тот же элемент - номер сообщения у него сбросится, и при удалениии регистрации при получении ответа - он не удалится, и будет послан с обменом ещё раз.

Так же если заключить всё в транзакцию - скорей всего юзер и не сможет записать элемент во время выполнения выгрузки
19 bolobol
 
18.10.13
18:08
(17) Тише, Mаксус, тише! Я про-ве-ря-ю... ))
20 bolobol
 
18.10.13
18:45
+100 Работает! Странно, но работает. Буду копать здесь.
Спасибо!!
21 Maxus43
 
18.10.13
18:58
(20) а почему странно? это стандартный механизм планов обмена, платформенный. Получив ответ от другой базы о загрузке - сама и удалит всю регистрацию правильно
22 bolobol
 
18.10.13
19:02
Не в этом смысле "Странно". Я пишу:
Выб= ПланыОбмена.ВыбратьИзменения(Узел, 1);

И у меня в таблицах все записи стали с номером 2... А:
Выб= ПланыОбмена.ВыбратьИзменения(Узел, 2);

- нормально работает, номера НОЛЬ сменились на 2 и все двойки остались.

В общем, прикол с 1 - не понял, ну да ладно))
23 ilya_i
 
18.10.13
19:04
интересно становиться когда надо дозировать выгрузку, например по времени. Было такое что накопилось изменений на два дня непрерывной выгрузки, а 1С столько работать не может, то ключ потеряет, то соединение.
24 SUA
 
18.10.13
19:04
(13)вариант 2
- выбираешь изменения (например объекты #1-#5)
- регистрируешь во 2й план обмена (объекты #1-#5)
- удаляешь из 1го (объекты #1-#5)
- делаешь что угодно со 2м
после п1 (известен состав объектов к переносу в фон)  - в 1й план обмена может добавляться что угодно
(20)работает но за номерацией следить самостоятельно
25 bolobol
 
18.10.13
19:14
(24) Вот, кстати, да - теперь понятно применение второго варианта, Спасибо! Однако...

ВыбратьИзменения(<Узел>, <НомерСообщения>, <ФильтрВыборки>)
<ФильтрВыборки> - это как раз то, чем и можно размер порции ограничить. Отобрал всё из узла в сообщение №2, получил первые Н объектов пакета и отобрал их в сообщение №3, третье и отправил. И так до тех пор, пока объектов для обмена не будет меньше Н, что уйдут за один приём. Вроде, должно взлетать)
26 ilya_i
 
18.10.13
19:26
Проблема в удалении регистрации, удаляя регистрацию сообщения номер 3, удалиться регистрация всех младших сообщений.
27 ProgAL
 
18.10.13
19:50
(25) Отпишитесь, пожалуйста, потом про правильный вариант.
28 ProgAL
 
20.10.13
16:57
Проверил на таблицах sql сервера как регистрируются данные при отправке. Вам подойдет следующий код. Взято из книги Гончарова. Ключевой момент - после записи выходного файла выполняется ПланыОбмена.УдалитьРегистрациюИзменений(ВыбУзел, НомерСообщения);  . Удалятся изменения только для тех элементов, которые содержали номера сообщений не превосходящие номер сообщения, сгенерированный во время метода ВыбратьИзменения(), и не будут удалены те, которые за время выгрузки приобрели NULL в качестве номера сообщения (т . е. за время выгрузки были еще раз изменены).

Процедура КнопкаВыполнитьНажатие(Кнопка)
    ИмяФайла = "D:\123.xml";
    
    НомерСообщения = 0;

    // Создаем объект записи XML
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл(ИмяФайла);
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    // Создаем новое сообщение
    ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
    ЗаписьСообщения.НачатьЗапись(ЗаписьXML, ВыбУзел);
    
    // Для сокращения размера файла сообщения записываем соответствие пространств имен
    ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema";);
    ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance";);
    ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8", "http://v8.1c.ru/data";);
    
    НомерСообщения = ЗаписьСообщения.НомерСообщения;
    Сообщение = Новый СообщениеПользователю();
    Сообщение.Текст = "    Номер сообщения: " + НомерСообщения;
    Сообщение.Сообщить();
                
    
    // Получаем выборку изменённых данных
    Счетчик = 0;
    ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, НомерСообщения);
    Пока ВыборкаИзменений.Следующий() Цикл
        Данные = ВыборкаИзменений.Получить();
#Если Клиент Тогда
        Счетчик = Счетчик + 1;
        Состояние("Выгрузка данных: " + Строка(Счетчик));
#КонецЕсли

        
        // Записываем данные в сообщение
        
        
        ЗаписатьXML(ЗаписьXML, Данные);

    КонецЦикла;
    
    // Завершаем запись сообщения
    ЗаписьСообщения.ЗакончитьЗапись();
    ЗаписьXML.Закрыть();
    
    ПланыОбмена.УдалитьРегистрациюИзменений(ВыбУзел, НомерСообщения);
    

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