Цялата истина за собственосттаBlockForChange, Станете експерт в 1C

станете

Мотивацията за написването на тази статия беше голям брой погрешни схващания относно свойството "LockToChange". По-голямата част от материалите в мрежата са или за управлявани заключвания, или за разделен тотален режим, свойството "LockToChange" е засегнато само частично без конкретика, в резултат на това мнозина имат въпроси, когато го използват. Нека да разберем какъв вид животно е и защо изобщо е необходимо.

Бъбривостта не струва нищо. Покажи ми кода.

За да разберете материала на тази статия, трябва да знаете и разбирате добре 2 неща:

1. Какво представлява режимът на разделени суми. Ако изведнъж не знаете, тогава препоръчвам да прочетете тази статия. Всичко е много подробно и ясно написано.

2. Нова методология за мониторинг на остатъчните вещества (остатъчните вещества се контролират след записване)

Режимът на разделени суми е много полезен, ако не е необходимо да проверявате баланси по регистър. възможно е да се записват данни със същия набор от измервания паралелно. Ако е необходимовинаги да контролирате балансите по регистър, тогава е по-добре да не използвате режима на разделени суми, т.к. Не дава никакво предимство в паралелизма. Но какво ще стане, ако например един регистър има 2 регистратора и единият документ използва контрола на баланса, а вторият не? В този случай свойството "LockForChange" на набора от записи на натрупване и счетоводни регистри ще ни бъде полезно.

Да започнем с това, че използването на "LockForChange" има смисъл само аковсички от следните условия са верни:

  • транзакцията се изпълнява в управляван режим (ако се използва в автоматичен режим, ще възникне грешка)
  • регистърът има активиран режим на разделяне на суми (ако е деактивиран, тогавасвойството няма значение и просто ще бъде игнорирано)
  • използва нова методология за мониторинг на остатъчните вещества (остатъчните вещества се контролират след записване)

Ако поне едно от 3-те условия не е изпълнено, тогава няма смисъл да използвате "BlockForChange". Следователно всичко от изброеното по-долу се прилага само ако са изпълнени и трите условия.

Какво прави това свойство?

Това свойство прави едно единствено нещо, деактивира общия разделител на набора от измерения, които се записват от момента на запис до края на транзакцията.

Някои са объркани от тази формулировка, а именно думите „деактивира разделителя на общите суми за записания набор от измервания“. За да стане по-ясно, ще кажа с други думи, ако зададем „LockForChange“ на „True“, тогава се прилага управлявано заключване, без да се взема предвид разделителят.

Според мен тези две формулировки са еднакви по смисъл, но в изпита 1C: Expert препоръчвам да използвате втората формулировка „контролираното заключване се наслагва, без да се взема предвид разделителят“, въпреки че по същество те описват едно и също явление.

Повече подробности?

Тук е необходимо да рисувате всяка фраза, за да изключите неправилно тълкуване.

"...деактивира общия разделител"

Въпреки името, това свойство всъщност не заключва нищо, наборът от записи се заключва автоматично от рамката, когато е написан. използва се управляван режим. Факт е, че когато се използва това свойство, разделителят няма да бъде взет предвид в момента на блокиране, ако свойството не се използва, тогава разделителят ще бъде взет предвид.

Тоест, заключването ще бъде приложено във всеки случай (независимо дали използвате свойството или не), но когато използвате "LockForChange", заключването ще бъде приложено, без да се взема предвидобщ сепаратор.

Защо изобщо да деактивирате общия разделител?

Ако общият разделител не е деактивиран, платформата налага контролирано заключване на ключа Склад+Артикул+Разделител.

В резултат на това са възможни следните последствия:

  • При използване на блокираща СУБД е възможно блокиране.
  • Когато използвате инструмент за версии, е възможно да отпишете салда в отрицателна стойност.

Нека разгледаме тези случаи по-подробно.

Ако се използва блокер.

В случай на блокер, безизходицата се оказва доста проста, две транзакции записват данните си паралелно според един набор от измервания, платформата позволява това, защото. се използва общият сепаратор. След това и двете транзакции искат да проверят балансите и това изисква всички редове по ключа Склад + Стоки (т.е. без да се взема предвид разделителят). В резултат на това никоя от транзакциите не може да прочете всички редове, защото част от редовете е уловена от друга транзакция (разделителят "предотвратява" улавянето на всички редове).

Схемата на тази безизходица е представена в таблицата.

експерт

В този случай по предназначение "LockToChange" е аналог на параметъра "ЗА ПРОМЯНА" в заявката за четене на салда в автоматичен режим, само че работи по различен начин.

Ако активирате „LockForChange“, тогава ще деактивираме разделителя на общите суми и при писане незабавно ще се приложи управлявано заключване Склад + Стоки и транзакция 2 няма да може да добави втори ред, защото този набор от измервания вече ще бъде заключен. Когато използвате "LockToChange", заключването на ключа Warehouse+Item е следствие от деактивирането на общия разделител, за да се предотврати блокиране. Можем да кажем, че това е един вид полезен страничен ефект.

Но дори и да не сме използвалиBlockForChange (и рискуваше да изпадне в задънена улица), тогава отрицателните салда пак нямаше да бъдат отписани, т.к. всички необходими редове за ключа Warehouse+Product (с изключение на разделителя) ще бъдат блокирани от заявка за салда.

Много объркване възниква поради името на това свойство, така че не е ясно веднага как работи. В този случай името не съответства на това, което всъщност прави свойството (не блокира нищо, деактивира разделителя), но името съответства на резултата (в крайна сметка заключваме всички записи, от които се нуждаем).

Ако се използва управление на версиите

В този случай заключените редове на първата транзакция по никакъв начин няма да попречат на втората транзакция да прочете остатъците (защото при управлението на версии писателите не блокират четците). Втората транзакция тихо ще прочете старата версия на данните (версията в началото на първата транзакция) и ще отпише остатъка на минус. За да се предотврати това, е необходимо контролирано блокиране на ниво 1C. Ако зададем LockToChange = True, просто ще получим такова заключване и данните ще бъдат заключени на ниво платформа.

„според записаните измервания“

Разделителят е деактивиран само за този набор от измервания.

Това означава, че режимът на разделяне на сумите в регистър като цяло се запазва и ако други набори от измерения имат BlockToChange = False, тогава те могат да бъдат записани паралелно.

Да кажем, че 6 транзакции са се срещнали едновременно и са се опитали едновременно да запишат данни в регистъра, докато общият разделител е естествено включен. Първите 2 транзакции правят разход и контролират баланса, останалите 4 носят доход и не е необходимо да контролират баланса.

Тогава получаваме тази картина.

Транзакция 1 се оказа част от секундата по-бърза от всички тях и вкъм момента на писане на данните, той е придобил изключителна управлявана ключалка, игнорирайки общия разделител (тъй като LockToChange = True). Транзакции 2 и 6 чакат транзакция 1, защото те имат еднакъв набор от измервания. В този случай няма значение коя стойност „LockToChange“ е зададена за транзакции 2 и 6, важното е, че наборът от измерения е един и същ и вече е заключен, така че те не могат да записват данните си паралелно. Транзакции 3 и 4 успешно записаха своите данни паралелно, защото разделителят е активиран (LockForChange = False). Транзакция 5 успешно записа данни паралелно, защото използва се набор от измерения, различни от транзакция 1.

"от момента на писане до края на транзакцията"

Общият разделител е деактивиран само в момента, в който започне записването на данни в регистъра и е валиден до края на транзакцията за осчетоводяване на документа. Това означава, че можете да активирате това свойство навсякъде в кода, но то ще влезе в сила само когато данните се записват в регистъра. В този случай собствеността е валидна до приключване на цялата сделка, т.е. ако записът в регистъра е завършен и транзакцията продължи, тогава имотът също продължава да работи. Така че ако транзакцията бъде отменена, свойството автоматично ще бъде зададено на False

Какво се случва, ако зададете LockToChange = True за регистър, който има изключени разделни суми?

Абсолютно нищо, дори няма да има грешка, само този ред от код ще бъде игнориран.

Какво ще кажете за изричните управлявани заключвания, вече не са ли необходими?

Да, това е още един плюс на този имот. Когато го използвате, не е необходимо да пишете изрични управлявани заключвания, един ред е достатъченMoves.CaseRequired.LockForChange = Вярно, това прави кода по-компактен и четим. Но си струва да запомните, че можете да използвате това свойство само ако са изпълнени трите условия, описани в началото на статията.

Мога ли пример?

Да предположим, че има документ за изпълнение, който се движи през един регистър с контрол на баланса, докато разделителят на сумите е включен за този регистър.

В този случай кодът на модула за поведение ще изглежда така:

Низът "Movement.Remains of Goods.LockForChange = True;" можете да пишете навсякъде в процедурата, за удобство е по-добре да го направите в края.

Кодът с проверката на остатъците може да се запише и в модула регистър набор от записи, но в този случай е необходима проверка за вида на документа, т.к. може би някои документи не се нуждаят от контрол.

Ако даден регистър винаги трябва да контролира салда, тогава в този случай, както беше споменато по-горе, е по-добре да деактивирате режима на разделяне на сумите за този регистър напълно. все още няма да има печалба при паралелна работа.

Изводи:

1. Това свойство трябва да се използва само ако са изпълнени всичките 3 условия:

  • транзакцията се изпълнява в управляван режим
  • регистърът има активиран режим на разделени суми
  • използва нова методология за мониторинг на остатъчните вещества (остатъчните вещества се контролират след записване)

2. Въпреки името, свойството не блокира нищо (блокирането се случва при писане във всеки случай), деактивира режима на разделяне на сумите, което води до блокиране на всички необходими записи (без да се взема предвид разделителят).

3. Когато използвате "LockForChange", не е необходимо да се задават изрични управлявани заключвания.