Telerik OpenAccess Classic

Telerik OpenAccess ORM Send comments on this topic.
Using Transactions in OpenAccess ORM
Programmer's Guide > OpenAccess ORM Classic (Old API) > Programming With OpenAccess > Transactions > Using Transactions in OpenAccess ORM

Glossary Item Box

This documentation article is a legacy resource describing the functionality of the deprecated OpenAccess Classic only. The contemporary documentation of Telerik OpenAccess ORM is available here.

Getting the Transaction for an Object Scope

All operations for a transaction are accessible through the OpenAccess.ITransaction interface. The ITransaction instance for a given object scope can be obtained by the IObjectScope.Transaction property. There is a one-to-one relationship between an object scope and a transaction; each IObjectScope instance has one implicitly defined ITransaction. The ITransaction instance does not change until IObjectScope.Dispose() is explicitly called. It is legal to use an ITransaction reference, as shown in the following example, rather than always accessing the Transaction property of the object scope.

In this example below, the ITransaction associated with the object scope is stored in a variable that can be used later in the application code.

C# Copy Code
IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
ITransaction txn = scope.Transaction;
VB.NET Copy Code
Dim scope As IObjectScope = ObjectScopeProvider1.GetNewObjectScope()
Dim txn As ITransaction = scope.Transaction

Begin, Commit

Before you can perform any operations on persistent class instances, you need to start a transaction. This is done with the ITransaction.Begin() method. Any modifications made to objects after beginning the transaction can be persistently written into the database by calling ITransaction.Commit(). The Commit() call attempts to write all modified objects into the database. If any error occurs, no modifications you have made since the Begin() call are written (atomicity principle).

In the following example, a new Customer object is stored in the database.

C# Copy Code
scope.Transaction.Begin();
Customer c = new Customer();
c.Name =
"Smith";
c.CustomerNo = 34567;
//the customer is added to the object scope . . .
scope.Add(c);
// here, the transaction is committed and
// all new and modified objects are stored
scope.Transaction.Commit();
VB.NET Copy Code
scope.Transaction.Begin()
Dim c As New Customer()
c.Name = "Smith"
c.CustomerNo = 34567
'the customer is added to the object scope . . .
scope.Add(c)
' here, the transaction is committed and
' all new and modified objects are stored
scope.Transaction.Commit()

If you need the in-memory objects to keep their values following a commit, you can use the transaction property RetainValues. This might be necessary if you want to access the objects from outside a transaction. The Transaction Properties section discusses this further.

Rollback

If, for some reason, you decide that the changes made within the transaction should not be made persistent, you can end the transaction with the Rollback() method and no changes will be written to the database.

The following example depends on user input to determine whether the name change to a Customer instance will be made persistent. The OK button results in a Commit() call, which attempts to write all modified objects into the database. The Cancel button results in a Rollback() call, which ends the transaction and no changes will be written to the database.

C# Copy Code
scope.Transaction.Begin();
// retrieve Customer instance from the database
Customer cust = (from c in scope.Extent<Customer>() where c.CustomerID=="ALFKIN" select c).First();
// modify the name in the persistent instance
cust.CompanyName = "New Name";
// check if changes should be made persistent
// (e.g., whether the OK or Cancel button was pressed)
bool doCommit = Check();
if(doCommit)
{
// the new values of c are stored automatically
scope.Transaction.Commit();
}
else
{
// rollback means the changes are not stored in the database
scope.Transaction.Rollback();
}  
VB.NET Copy Code
scope.Transaction.Begin()
' retrieve Customer instance from the database
Dim cust As Customer = (From c In scope.Extent(Of Customer)() _
 Where c.CustomerID = "ALFKIN" _
 Select c).First()
' modify the name in the persistent instance
cust.CompanyName = "New Name"
' check if changes should be made persistent
' (e.g., whether the OK or Cancel button was pressed)
Dim doCommit As Boolean = Check()
If doCommit Then
 ' the new values of c are stored automatically
 scope.Transaction.Commit()
Else
 ' rollback means the changes are not stored in the database
 scope.Transaction.Rollback()
End If

The rollback operation terminates the transaction without writing any changes to the database. The in-memory objects will be "refreshed" from the database (reloaded with their original data) the next time they are accessed within a subsequent transaction.

If you need the in-memory objects to revert to their original values immediately following a rollback, you can use the transaction property RestoreValues. This might be necessary if you want the objects to have the correct value when used from outside a transaction. The Transaction Properties section discusses this further.

Even if you call Commit(), the transaction may be rolled back if an error is encountered while writing the new or modified objects to the database. This follows from the atomicity property of transactions. An example of a potential error is an index key violation for a unique index. In the example above, if the Customer class has a unique index for the name field and the new name conflicts with a Customer instance already present in the database, the commit will fail with a DuplicateKeyException error. In this case, the entire transaction is rolled back. The transaction may be restarted and the application can take steps to rectify the error.

Closing a Database with Open Transactions

The IObjectScope.Dispose() method throws an exception if the transaction is active. You can check if an IObjectScope instance has an active transaction with the method ITransaction.IsActive(). This example checks if the current transaction is active before disposing of the IObjectScope instance.

C# Copy Code
// determine if the transaction is active or terminated

if ( scope.Transaction.IsActive )

{

   scope.Transaction.Rollback();

}

scope.Dispose();
VB.NET Copy Code
' determine if the transaction is active or terminated
If scope.Transaction.IsActive Then

 scope.Transaction.Rollback()
End If
scope.Dispose()