This chapter explains how to work with transactions in Kentico CMS API. Transactions are usually used to ensure database consistency.
Native transactions
Kentico CMS uses SQL transactions to ensure the system database consistency when performing complex operations consisting of multiple steps. In such cases the whole operation forms a single block of SQL commands that can be rolled back when an error occurs or committed if the complete operation was successful. Transaction handling is provided by CMS.DataEngine library, in the GeneralConnection class.
Please note that you should always use single connection for every operation within the open transaction to avoid deadlocks.
The transactions flow in Kentico CMS looks like this:
Please note: Always pass the existing connection as a method parameter if you call the method that uses DB access within transaction.
Example
Please use following example as a template in all the methods that work with transactions:
[C#]
using CMS.DataEngine; using CMS.TreeEngine; using CMS.FileManager; using CMS.WorkflowEngine;
/// <summary> /// Sample method /// </summary> /// <param name="conn">Data connection to use</param>
public void DoSomethingInTransaction(GeneralConnection conn) {
// Process within transaction using (var tr = new CMSTransactionScope(conn)) { // --- HERE YOU CAN USE YOUR DATABASE ACCESS CODE LIKE: ---- DataSet ds = conn.ExecuteQuery("cms.user.selectall", null, null, null);
// --- IF YOU NEED TO USE TREEPROVIDER, ALWAYS INSTATIATE IT WITH EXISTING CONNECTION TreeProvider tree = new TreeProvider(null, conn);
// --- ALWAYS USE METHOD OVERRIDES THAT USE CONNECTION (TREEPROVIDER) PARAMETER --- AttachmentInfo ai = DocumentHelper.GetAttachment(Guid.NewGuid(), 1, tree);
// Commit transaction tr.Commit(); }
} |
You may also work with TreeProvider class instead of connection object. In that case, use its Connection property the same way like the GeneralConnection in this example and use the same connection object in all operations inside the transaction.