1Ci Support Help Center home page
Submit a request
Sign in
  1. 1Ci Support
  2. 1C:Enterprise Development Standards
  3. Data processing
  4. Data processing and modification

Transactions: rules of use

  • Data processing and modification
    • Transactions: rules of use
    • Using managed lock mode
    • Locking object data for editing from code
    • Responsible data reading
    • Reading specific object attributes from the database
    • Writing events to the user operations history

Scope: managed applications, mobile applications, and ordinary applications.

Transactions are used for holistic change of related data. It means that all database operations within a transaction are either executed entirely or rolled back entirely.

1.Transaction usage in 1C:Enterprise has the following specifics:

  • Nested transactions are not supported. For more information, see Transaction nesting.
  • In general, if an exception is thrown, a transaction cannot be committed. It does not matter if this exception was processed or not. For more information, see Database errors and transactions and Specifics of using objects when rolling back transactions.
  • You can initiate a transaction explicitly in the application code using the BeginTransaction method. 1C:Enterprise platform implicitly starts the transaction upon any record to the database. For more information, see Platform documentation. Transactions functionality.

These specifics impose particular requirements for writing the code using transactions. If these requirements are not met, errors "Errors already occurred in this transaction" might occur. It might be very difficult to reproduce and debug these errors.

1.1. As an exception does not roll back a transaction immediately but prevents it from being successfully completed, all BeginTransaction calls on one side and CommitTransaction or RollbackTransaction calls on the other side are to be paired.

1.2. The transaction start and its commitment or cancellation must occur in the context of one method.

Correct:

Procedure WriteDataToIB()

    BeginTransaction();

    Try
        ... // Reading or writing data
        DocumentObject.Write()
        CommitTransaction();
    Except
        RollbackTransaction();
        ... // Additional actions to process the exception
    EndTry;

EndProcedure

Incorrect:

Procedure WriteDataToIB()
 
    Begin Transaction();
    WriteDocument();

EndProcedure;

Procedure WriteDocument()

    Try
        ... // Reading or writing data
        DocumentObject.Write()
        CommitTransaction();
    Except
        RollbackTransaction();
    ... // Additional actions to process the exception
    EndTry;

EndProcedure

1.3. When using transactions, you need to configure processing of exceptions. Adhere to the following rules:

  • The BeginTransaction method must be outside the Try - Except block, directly before the Try operator.
  • All actions being executed after calling the BeginTransaction method must be in one Try block, including data reading, locking, and processing.
  • The CommitTransaction method must be the last in the Try block before the Exception operator. This is required to ensure that no exception will be thrown after the CommitTransaction method.
  • Configure processing of exceptions. In the Except block, call the RollbackTransaction method first, and then perform other actions if required.
  • It is recommended that you make a record to the event log in the Except block.
  • When using nested transactions (see cl. 1.4), it is recommended that you add the Raise operator at the end of the Except block.  Otherwise, an exception will not be passed up the call stack. The exception will not be processed there, the external transaction will not be explicitly rolled back, and the platform will raise the exception "An error occurred in this transaction".

Example:

BeginTransaction();
Try
    DataLock = New DataLock;
    DataLockItem = DataLock.Add("Document.PurchaseInvoice");
    DataLockItem.SetValue("Ref", RefToProcess);
    DataLockItem.Mode = DataLockMode.Exclusive;
    DataLock.Lock();

    ... // Reading or writing data

    DocumentObject.Write();

    CommitTransaction();
Except
    RollbackTransaction();

    WriteLogEvent(NStr("en = "Execute operation""),
        EventLogLevel.Error,
        ,
        ,
        DetailErrorDescription (ErrorInfo()));

    Raise; // There is an external transaction

EndTry;

1.4. Nested transactions complicate the code. When deciding whether to use this feature, you need to evaluate the task very carefully. The increased complexity might be not reasonable.

1.4.1. You do not need to complicate the code using the BeginTransaction method explicitly when no other actions with the database, except for the object writing, are performed. The platform opens a transaction automatically upon writing.

You do not need to explicitly open the transaction when it is not required to execute mission-critical data reading. For example, usually, mission-critical reading is not required upon writing a new object or a new set of register records.

When using the GetObject or Read methods for record sets, you need to analyze whether the reading is to be mission-critical. Depending on this, decide whether to use the BeginTransaction method explicitly.

Correct:

Try
    DocumentObject = Documents.PurchaseInvoice.CreateDocument();
    ... // Actions to fill in an object
    DocumentObject.Write();
Except
    ... // Actions to process an exception
EndTry;

Incorrect:

BeginTransaction();
Try
    DocumentObject = Documents.PurchaseInvoice.CreateDocument();
    ... // Actions to fill in an object
    DocumentObject.Write();
    CommitTransaction();
Except
    RollbackTransaction();
EndTry;

1.4.2. If the method is supposed to be called only within an already opened transaction (for example, the method is called only from the BeforeWrite, Posting events, and so on), in general, it makes no practical sense to explicitly open the transaction in it.

1.4.3. If it is necessary to improve the quality of error messages, at each level, a developer can configure own exception processing. For this, it might be required to open a nested transaction.

Example:

The AddDigitalSignature method is called. If something went wrong, you need to process an exception inside and add the following text: "Cannot add a digital signature to object %ObjectPresentation% due to:%ErrorDescription%". Otherwise, the exception will be processed up the call stack, for example, when writing a file. The following message will be displayed: "Cannot write file %FileName% due to: %ErrorDescription%". The "%ErrorDescription%" will contain only a code line. It will be not clear for a user why the application tried to write the file if the user only signed it.

1.4.4. When processing an exception, if the transaction is still active, for example, the exception occurred in the nested transaction, do not access the database. Otherwise, it leads to the exception: "Errors already occurred in this transaction". Remember that the database can be accessed implicitly, for example, to get a reference presentation.

2. Transaction length limitation.

2.1. In general, only transactions that cannot be separated according to the business logic need to be performed within a single transaction.

Example:

When posting a document, the document and its records in registers are written. If at least one register record cannot be written, the entire posting transaction must be rolled back.

2.1.1. If actions can be performed separately according to the business logic, in general, you do not need to combine them into one transaction.

2.1.2. An exception to cl. 2.1.1 might be cases when several unrelated objects are processed within one transaction for optimization purpose. In this case, choose a batch of data processing carefully: you need to strike a balance between duration of one transaction and amount of recorded data on the one hand and the number of transactions on the other hand.

2.2. Avoid transactions that take a long time.

Example

Incorrect:

To load FIAS address classifier, write all data related to one classifier version to one transaction in order to completely roll back the loaded classifier version in case of an error.

As there is a lot of data for one classifier version (volume of about 1 GB), firstly, the amount of RAM might be insufficient to execute such transaction (especially when using a file infobase on a 32-bit OS). Secondly, such operation takes a long period of time, and it cannot be optimized due to execution in several threads.

Correct:

Break loading of the new FIAS classifier version into small transactions and implement the functionality of rolling back to the previous version in case of an error.

See also Specifics of using transactions upon data exchange

2.2.1. The more time a transaction takes, the longer resources of 1C:Enterprise server and DBMS will be taken up. Usually, long transactions take up the following resources:

  • During a transaction, all changes in the database are written to the transaction log. It is required to be able to roll back the transaction.
  • Locks set in the transaction remain until the transaction end.
  • Locks take up RAM on 1C:Enterprise server.
  • Other resources required for the business logic that is implemented in the transaction.

All of this can reduce efficiency of resource usage.

2.2.2. If two transactions overlap in locked resources, the transaction that started later waits to set a lock for a limited time (by default, 20 seconds). After that, this transaction is completed with the exception "Time to set a lock is exceeded". Therefore, long transactions can significantly reduce convenience of concurrent user actions.

If such exceptions are thrown, you need to analyze actions performed in conflicting transactions:

  • Perhaps, you can move some actions out of the transaction (see cl. 2.4).
  • If you cannot move an action out of the transaction, try to optimize its execution algorithm.
  • You also need to analyze whether locks are optimally set. See standard group Excessive locks and optimization methods.

2.3. Within a transaction, you need to execute the minimum number of actions, only those that cannot be executed outside the transaction according to the business logic. In particular:

  • Complex resource-intensive calculations are to be made before the transaction start if the business logic allows it.
  • If the calculation is performed in the transaction, you need to make it as simple as possible. For example, you can perform balance control after writing using a simple query to the register being recorded.
  • Object filling is to be checked outside the transaction. See Checks inside and outside object write transactions.
  • You need to execute queries, before which it is not necessary to set a data lock, before the transaction start. See Mission-critical data reading.
  • You need to optimize queries performed within transactions. See standard group Optimizing queries.
© 2020-2021 1C INTERNATIONAL LLC www.1Ci.com Support policy