Skip to main content
A newer version of this page is available. .

Using Explicit Transactions

  • 4 minutes to read

An explicit transaction represents a database transaction that is explicitly started within a session or unit of work to isolate and finalize transactional changes at the database level. An explicit transaction allows you to easily manage object changes and also comes in handy in scenarios when normal transactions cannot be used for batch object updates.

XPO intrinsically starts a short explicit transaction, only to commit changes made in a transaction to a database, and then automatically closes the transaction, to avoid concurrency issues. You can manually maintain an explicit transaction within a session or unit of work using the Session.ExplicitBeginTransaction, Session.ExplicitCommitTransaction and Session.ExplicitRollbackTransaction methods as shown below.

using (UnitOfWork uow = new UnitOfWork(session1.DataLayer))
{
    Person person = new Person(uow);
    person.Name = "Thomas Brown";
    person.Age = 33;

    // Starts an explicit transaction.
    uow.ExplicitBeginTransaction();
    try {
        uow.CommitChanges();

        // person has been temporarily stored to a database, thus FindObject locates this person.
        Person savedPerson = uow.FindObject<Person>(CriteriaOperator.Parse(
            "Name = ? And Age = ?", person.Name, person.Age));

        savedPerson.Name = "James Smith";
        savedPerson.Age = 60;

        // Updates person with new data.
        uow.CommitChanges();
        // Finalizes changes and closes the explicit transaction.
        uow.ExplicitCommitTransaction();
    } catch {
        // Rolls back changes and closes the explicit transaction.
        uow.ExplicitRollbackTransaction();
        throw;
    }
}

To simplify the management of explicit transactions, explicit units of work have been implemented. These units of work automatically start an explicit transaction before object changes are temporarily saved to a database for the first time. Intermediate object changes are also automatically tracked, so that you can access modified objects without having to commit the changes beforehand.

The following code snippet demonstrates how to simplify the code demonstrated above, using an explicit unit of work.

using (ExplicitUnitOfWork euow = new ExplicitUnitOfWork(session1.DataLayer)) {
    // Starts tracking changes to persistent objects.
    Person person = new Person(euow);
    person.Name = "Thomas Brown";
    person.Age = 33;

    // Starts an explicit transaction and flushes all intermediate object changes to a database.
    // Thus, person has been temporarily stored to a database and FindObject locates this person.
    Person savedPerson = euow.FindObject<Person>(CriteriaOperator.Parse(
        "Name = ? And Age = ?", person.Name, person.Age));

    savedPerson.Name = "James Smith";
    savedPerson.Age = 60;

    // Updates person with new data and commits the explicit transaction.
    euow.CommitChanges();
}

Note

The ExplicitBeginTransaction, ExplicitCommitTransaction and ExplicitRollbackTransaction methods cannot be used with explicit units of work, because they are automatically called at appropriate moments.

Important

A Session or Unit of Work that starts an explicit transaction must be the exclusive owner of the database connection. Therefore, only one explicit transaction can be open at a time.