|   |   | 
| 
 | Как правильно разруливать такие ситуации (грязное чтение) | ☑ | ||
|---|---|---|---|---|
| 0
    
        degot 04.11.14✎ 12:38 | 
        Предположим есть такая ситуация : есть какие-то документы, которые проводятся длительное время. И есть процесс , в котором делаются запросы к таблице данного вида документов. Результат запроса обрабатывается, создаются объекты базы данных со ссылкой на на те самые документы. 
 Но бывают ситуации когда документ в итоге не проведется, в итоге объекты получаются с битыми ссылками на документы . В общем как правильно обрабатывать такие ситуации? Как исключить из запроса доки, по которым транзакция не завершена? Спасибо платформа 8.2, управляемый режим блокировок, sql 2012 | |||
| 1
    
        Bober 04.11.14✎ 12:41 | 
        (0) перед выполнение запроса НачатьТранзакцию(), после выполнения ОтменитьТранзакцию().     | |||
| 2
    
        Armando 04.11.14✎ 12:49 | ||||
| 3
    
        Armando 04.11.14✎ 12:58 | 
        Можно перед тем как выполнится это "создаются объекты базы данных со ссылкой на на те самые документы." накладывать исключительную блокировку на документ. Если не заблокировалось, значит с документом что-то происходит.     | |||
| 4
    
        herfis 04.11.14✎ 13:20 | 
        (0) Если именно "исключить из запроса доки, по которым транзакция не завершена", тогда (1) - чтение в транзакции READ COMMITTED, а не "грязное".     | |||
| 5
    
        Armando 04.11.14✎ 13:23 | 
        Кстати на 8.3 эту проблему вроде решили     | |||
| 6
    
        AlexITGround 04.11.14✎ 13:25 | 
        (4) мсье, не ругайтесь такими словами, ТС-а может спугнуть такой внезапный тон     | |||
| 7
    
        floody 04.11.14✎ 14:06 | 
        (1) прав, в 1С грязное чтение только вне транзакции. все, что в транзакции (явной или неявной) - это уже минимум read committed     | |||
| 8
    
        floody 04.11.14✎ 14:08 | 
        (0) если у вас какой-то документ проводится - это значит что он уже записан
 причем тут битые ссылки? битые образуются, если документ удалить без контроля ссылочной целостности | |||
| 9
    
        Armando 04.11.14✎ 14:11 | 
        (8) Может там при проведении Отказ = Истина     | |||
| 10
    
        Web00001 04.11.14✎ 14:29 | 
        (9)дык это же все равно, документ то есть, а проведен он или нет, это дело уже 10е.     | |||
| 11
    
        Armando 04.11.14✎ 14:35 | 
        (10) Создай новый документ, в при записи или обработке проведения сделай отказ, и попробуй провести его. Он у тебя не проведется и не запишется. Ну то есть в момент проведения ссыль будет, отказ заставит откатить транзакцию, и ссылки не станет.     | |||
| 12
    
        vi0 04.11.14✎ 15:05 | 
        (0) расскажи что за задачу решаешь
 зачем "исключить из запроса доки, по которым транзакция не завершена"? ты их потом будешь отдельно обрабатывать? эти документы по которым транзакция уже будет завершена | |||
| 13
    
        floody 04.11.14✎ 15:17 | 
        (11) это верно в том случае, если вы создали документ и записываете его программно с режимом "проведение"
 в конфигурациях обычно у пользователя документ сначала записывается, потом уже проводится | |||
| 14
    
        Armando 04.11.14✎ 15:21 | 
        (13) "конфигурациях обычно у пользователя документ сначала записывается, потом уже проводится"
 проверить не желаешь? | |||
| 15
    
        herfis 04.11.14✎ 16:05 | 
        (13) Чушь какая-то. Проведение на 8-ке всегда было частью транзакции записи. Или появились быдло-типовые, где проведение нового документа разбито на две транзакции?     | |||
| 16
    
        degot 04.11.14✎ 16:34 | 
        (12) да, они обработаются следующим заходом     | |||
| 17
    
        Обработка 04.11.14✎ 16:39 | 
        (0)
 В запросе у вас должно быть проверка "ссылка.проведен". Если документ записан но не проведен тогда не попадет в ваш запрос. А если уж поапл тогда значит документ уже провелся. Если документ перепроводится эо уже другой случай. | |||
| 18
    
        Зеленый пень 04.11.14✎ 16:51 | 
        (0) "Результат запроса обрабатывается, создаются объекты базы данных со ссылкой на на те самые документы." - в этот момент накладывать блокировку на документы из запроса, если удалось - всё ок.     | |||
| 19
    
        vi0 04.11.14✎ 17:02 | 
        (18) не, если ТС говорит про битые ссылки на документы, значит достаточно запрос делать в транзации - запрос не увидит эти документы т.к. чтение не будет грязным     | |||
| 20
    
        tridog 04.11.14✎ 18:10 | 
        (17) Если документ проведен, но транзакция еще не зафиксирована - то при грязном чтении параллельный сеанс вполне себе прочитает незафиксированное состояние через условие вида "Ссылка.Проведен".
 Ваш совет ничем не отличается от исходной ситуации в (0). Единственный (и правильный) вариант избежать подобного - получить при чтении уровень изоляции, при котором не будет чтения изменений незафиксированных транзакций. Как уже писали Выше - самый простой вариант - это выполнять чтение в транзакции, тем самым получив в СУБД уровень изоляции Read committed. Вообще говоря, для современных конфигураций (управляемые блокировки, режим совместимости 8.3 и т.д.) - уже сложно найти причины, которые бы делали чтение вне транзакции обоснованным. | |||
| 21
    
        vi0 04.11.14✎ 18:22 | 
        > выполнять чтение в транзакции, тем самым получив в СУБД уровень изоляции Read committed.
 у него управляемые блокировки, поэтому до субд не дойдет > уже сложно найти причины, которые бы делали чтение вне транзакции обоснованным. отчеты, по прежнему, логично выполнять вне транзакции | |||
| 22
    
        tridog 04.11.14✎ 18:44 | 
        (21) > у него управляемые блокировки, поэтому до субд не дойдет 
 Мы говорим про уровень изоляции при чтении. Чтение до СУБД дойдет в любом случае (вместе с уровнем изоляции). Управляемые блокировки этому не помешают. > отчеты, по прежнему, логично выполнять вне транзакции Ну они действительно так и формируются на текущей платформе. А какие от этого плюсы? | |||
| 23
    
        vi0 04.11.14✎ 19:22 | 
        (22) почему не помешают?
 Про плюсы. Транзакции всегда ипользуют ресурсы и задействовать их есть смысл, когда будет реальная необходимость | |||
| 24
    
        Armando 04.11.14✎ 19:40 | 
        Вот в тему про 8.3:
 http://downloads.v8.1c.ru/content//Platform/8_3_5_1248/1cv8upd.htm#4cc794a4-7d56-11e1-b5d1-e61f135f174b Как было: Microsoft SQL Server 2005 и выше использовался в режиме блокировок. Использовался уровень изоляции транзакций READ_COMMITED. При чтении вне транзакций использовалось «грязное» чтение. Как стало: При работе с Microsoft SQL Server версии 2005 и выше, используется режим управления версиями строк, если конфигурация использует режим управляемых блокировок. Используется уровень изоляции транзакций READ_COMMITED_SNAPSHOT. При чтении данных вне транзакций используется согласованное чтение. Реализованные изменения приводят: К уменьшению блокировок и взаимоблокировок при выполнении запросов, работающих в транзакции; Исчезновению ошибок при выполнении запросов вне транзакции над часто модифицируемыми прикладными объектами; Получению согласованных результатов отчета вне транзакции на момент выполнения отчета. | |||
| 25
    
        tridog 04.11.14✎ 19:45 | 
        (23) Потому что собственный менеджер блокировок внутри платформы не может влиять на то, как СУБД читает данные.     | |||
| 26
    
        vi0 04.11.14✎ 19:50 | 
        (25) я говорил, что упр блокировки работать будут и при чтении, и блокировки субд тут вторичны     | |||
| 27
    
        tridog 04.11.14✎ 20:06 | 
        (26) Мне кажется, что Вы несколько не до конца разобрались с тем, что такое управляемые блокировки.
 Могу прокомментировать Ваше высказывание так: 1. При выполнении запросов управляемые блокировки сами по себе не устанавливаются. Вообще :) Чтобы бы устанавливались управляемые блокировки при чтении - нужно либо устанавливать их из встроенного языка (объект БлокировкаДанных), либо выполнять чтение не через запросы, а через объектную технику (РегистрСведенийМенеджерЗаписи и т.д.). 2. При чтении вне транзакции управляемые блокировки вообще не могут устанавливаться - можно проверить через объект БлокировкаДанных и техжурнал по событию TLOCK. Кстати в офф. документации (а не на "сленге") они называются транзакционными блокировками, а не управляемыми. 3. Использование управляемых блокировок не отменяет блокировок в СУБД, и неправильно считать, что блокировки СУБД вторичны. Например, даже при использовании управляемых блокировок реальны ситуации избыточных блокировок в СУБД - по-максимуму такие ситуации исключены в 8.3 без режима совместимости, как тут уже выше писали. 4. То, "прочитаются" ли запросом данные параллельных незафиксированных транзакций вообще никак не зависит от блокировок! Ни от блокировок в СУБД, ни тем более, от управляемых блокировок. А зависит только от уровня изоляции транзакций, которым мы можем управлять только неявно. Что автору и было посоветовано - в виде выполнения запроса в транзакции. | |||
| 28
    
        vi0 04.11.14✎ 22:28 | 
        1. согласен
 2. 3. зачем вы это написали? 4. странный абзац с учетом того, что уровень изоляции как раз задает, как именно будут блокироваться данные еще странно советовать автору рулить блокировками СУБД (уровнем изоляции) при том что конфигурация у него на управляемых | |||
| 29
    
        Ник второй 04.11.14✎ 22:38 | 
        (27) 
 1. Ложь. Блокировки ставятся всегда 2. Привыполнении запроса ставится блокировка на чтении, смотри профайлер 4. мда, (28) в части 4 пункта +1 | |||
| 30
    
        tridog 04.11.14✎ 23:06 | 
        (28) Уровень изоляции задает не только стратегию блокировки данных при чтении. Еще, например, стратегию чтения данных, заблокированных другой транзакцией (несогласованное чтение).
 > При том что конфигурация у него на управляемых Управляемые блокировки в этом случае (выполнение запроса) вообще не устанавливаются. При чем тут они - непонятно. При выполнении запроса вне транзакции допускается несогласованное чтение (до 8.3 без совместимости). При выполнении запроса в транзакции в этом случае платформа использует READ_COMMITED - что ликвидирует грязное чтение. Это и было посоветовано автору, притом сразу в первом ответе) (29) Профайлер показывает блокировки СУБД. Речь шла про управляемые блокировки (это отдельно подчеркивалось). | |||
| 31
    
        Torquader 04.11.14✎ 23:41 | 
        Начнём с того, что если мы открываем транзакцию и обращаемся к объекту, изменённому в другой ещё неподтверждённой транзакции, то будет блокировка и транзакция будет ожидать завершения транзакции проведения.
 Однако, возможна ситуация, когда при проведении данные для записи в таблицы (например, регистры) готовятся, но ещё не были записаны - в этом случае - транзакция чтения получит старые данные, и ничего удивительного в этом нет. | |||
| 32
    
        vi0 05.11.14✎ 07:57 | 
        (30) еще раз: зачем ему советовать инструменты субд, 8.3 и прочее, когда он написал, что у него 8.2 управляемые блокировки - для этого есть соответствующие инструменты     | |||
| 33
    
        vi0 05.11.14✎ 08:02 | 
        (29) всегда ставятся упр блокировки?
 а можно пример кода? | |||
| 34
    
        tridog 05.11.14✎ 08:16 | 
        (32) Инструменты СУБД ему никто не советовал. Ему посоветовали выполнять запрос в транзакции - изменив непосредственно код на встроенном языке.
 Описание того, почему это изменит ситуацию я привел в ответ на совет добавить в запрос условие вида Ссылка.Проведен. Соответствующие инструменты для того, чтобы избежать грязного чтения на 8.2 (хоть на управляемых блокировках, хоть на автоматических) - это выполнять чтение в транзакции. Само по себе использование управляемых блокировок не отменяет грязного чтения. Попутно много раз было отмечено (не только мной), что на 8.3+ проблемы вообше нет в принципе из-за изменений в платформе (всегда считал, что это полезная информация). | |||
| 35
    
        herfis 05.11.14✎ 10:30 | 
        (34) "на 8.3+ проблемы вообше нет в принципе из-за изменений в платформе"
 Не совсем так. Проблема не в платформе, а логике работы используемой СУБД. В версионниках этой проблемы и не было никогда. В postgres, например. Просто 8.3+ научилась работать с MSSQL в режиме версионника, который там с некоторых пор появился (см. 24) Как дела обстоят в DB2 точно не знаю, но вроде как он остался чистым блокировочником а значит и грязное чтение вне транзакций в 1С там осталось скорее всего. | |||
| 36
    
        degot 05.11.14✎ 11:03 | 
        (35) а вы случаем не в курсе, будет ли 8.3 работать  с версиями, если конфа в режиме совместимости?     | |||
| 37
    
        herfis 05.11.14✎ 12:13 | 
        (36) Не в курсе.     | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |