Scope: managed applications, mobile applications, and ordinary applications.
1.1. In some cases, locking reading of totals is required. For example, balance control upon posting documents. If once a document is posted, the balance becomes negative, cancel the transaction. Such document cannot be posted.
Otherwise, two users can simultaneously read the same balance (for example, 10 items) and decide to write them off. If the write-off amount of two users is greater than 10, the balance is negative.
For example, the first user writes off 8 items (8 is less than 10, the operation is allowed). The second user writes off 6 items. As a result, you have a negative balance (-4 items). It is unacceptable from the application logic context.
As a rule, developers do not control the sequence, in which records are written to registers. It is controlled automatically by 1C:Enterprise platform. Balance control query is implemented in the record set module and called upon writing register records. If this register is written at the beginning of the transaction (for example, first), the lock prevents other users from performing operations for a long time (until all other registers are written). The system performance can be significantly affected.
In some cases, there is no need to control balance as records being written cannot generate negative balance.
To minimize effect of locking reading of balance on the system performance:
Analyze which balances require locking reading and what the conditions are. For example, no balance control is required upon posting receiving documents as it only increases the balance. Balance control is also not required upon reposting documents that write off the same or less balance than upon the first posting. This control is already made.
At the beginning of the transaction (for example, in the Posting document handler), explicitly write records for all registers that do not require balance control in this case. Always use the same order of writing registers (for example, the alphabetical order). Make sure all accumulation and accounting registers being written have an active totals separator, and the LockForUpdate property is set to False for record sets.
Perform all other operations required for this transaction.
At the end of the transaction, explicitly write records for the registers that require balance control. Set LockForUpdate to True for record sets of these registers. It is required to prevent deadlock. In this case, when writing a record set, register balance is locked for the dimension value set.
Execute a balance control query for each register. Note that in this case it is not required to use an explicit managed lock (FOR UPDATE in the automatic mode) as the balance being checked was already locked when being written at the previous stage. Make sure the query reads only negative balance for the specified set of dimension values. If such records exist, cancel the transaction. If a query returns an empty result, commit the transaction.
In the BeforeWrite procedure of the record set module of the SelfFinancing accounting register, the following query is executed:
Query.Text = "SELECT
| AccountingRegister.SelfFinancing.Balance(&Period, &Account, , Company = &Company)";
Upon executing this query, balance is read (and locked from writing) by the specified condition for all user connections. Different resources (created by the totals separation mode) are grouped. For that reason, simultaneous actions are the same as if the totals separation mode is not enabled.
To minimize influence of this lock on the overall system performance, transfer it to the transaction end. For example, you can transfer this check to the OnPost event handler in the document module after explicitly writing all records for all registers.