Telerik OpenAccess Classic

Telerik OpenAccess ORM Send comments on this topic.
ObjectScopes,Transactions and Threads
Programmer's Guide > OpenAccess ORM Classic (Old API) > Programming With OpenAccess > Transactions > ObjectScopes,Transactions and Threads

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.

The following section describes issues related to multi-threading, while working with OpenAccess ORM:

Relationship between an ObjectScope transaction and a Database transaction

An ObjectScope instance is at any point in time associated with zero or one connection to the database, for e.g., an SQLConnection when ADO .NET is used as an underlying driver.

There are two types of transactions:

Scope Transactions – These can be long-running transactions and they are more flexible than database transactions. Also please read the example that appears under the Rollback section. The example describes starting a transaction, opening a popup, getting some user input and then calling Commit() on OK or Rollback() on Cancel.

Database Transactions – These must be short transactions

OpenAccess ORM offers the choice of using optimistic or pessimistic concurrency control. When OpenAccess ORM and Optimistic Concurrency Control are used together, there is only a loose coupling of underlying database connections and ObjectScope instances. An ObjectScope is only associated with a database connection, while specific operations (such as fetching objects from the database or during a Commit() calls) lasts, after which the connection is returned to the pool. This allows for higher concurrency, and the concurrency control is mostly performed by OpenAccess ORM, during commit time. In this case, the database is not primarily responsible for concurrency control (as is the case with pessimistic concurrency control).

However, certain operations cause the database connection to be pinned to one ObjectScope until the transaction ends, even with optimistic concurrency control. Some examples of when this happens are given below:

Queries where IgnoreUncommited is set to "false", since in this case, all the changes have to be flushed to the database before executing the query. To be able to rollback these changes, the transaction connections must remain active and the association to the ObjectScope must be maintained.

GetObjectId calls, which trigger a database INSERT (e.g. with AUTOINC keys) pin the underlying connection to the ObjectScope until the transaction ends.

When ITransaction.Flush() is called.

When Explicit locking is set.

However in case of Pessimistic Concurrency control, most of the work is done by the database itself, while the transaction lasts, i.e., from Transaction.Begin() to Transaction.Commit()/Transaction.Rollback(), the same low-level database connection is associated with the ObjectScope. Also, the transaction boundary events are passed 1:1 to the underlying connection, i.e., both the database transaction and the ObjectScope transaction are active exactly at the same time. In other words, this means that the database transaction is begun, once the ObjectScope's transaction begins, and the database transactions ends, once the ObjectScope's transaction ends.

One Thread, One ObjectScope

Your application program has one thread using one transaction at a time. This is the easiest to program and is usually adequate for most simple applications.

Multiple Threads With Their Own ObjectScopes

You can use multiple threads, each with its own ObjectScope. This approach is not much more difficult when compared with the one-thread, one-ObjectScope approach. The benefit of this approach is that multiple threads (application server threads, etc.) can run in parallel and the OpenAccess ORM runtime system will handle the concurrency issues.

Multiple threads, each associated with a single, non-shared ObjectScope, is a common multi-threading alternative. In the following example, each thread uses its own associated IObjectScope instance.

C# Copy Code
public class MultipleThreadsExample
{
const string connectionId = "DatabaseConnection1";
// The ThreadProc method is called when the thread starts.
public static void ThreadProc()
{
// each thread has its own object scope
IObjectScope scope =
Database.Get(connectionId).GetObjectScope();
scope.Transaction.Begin();
// do some work...
scope.Transaction.Commit();
}
public static void Main()
{
Thread t1 =
new Thread(new ThreadStart(ThreadProc));
Thread t2 =
new Thread(new ThreadStart(ThreadProc));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
}
}  
VB.NET Copy Code
Public Class MultipleThreadsExample
 Const connectionId As String = "DatabaseConnection1"
 ' The ThreadProc method is called when the thread starts.
 Public Shared Sub ThreadProc()
  ' each thread has its own object scope
  Dim scope As IObjectScope = Database.[Get](connectionId).GetObjectScope()
  scope.Transaction.Begin()
  ' do some work...
  scope.Transaction.Commit()
 End Sub
 Public Shared Sub Main()
  Dim t1 As New Thread(New ThreadStart(ThreadProc))
  Dim t2 As New Thread(New ThreadStart(ThreadProc))
  t1.Start()
  t2.Start()
  t1.Join()
  t2.Join()
 End Sub
End Class

Multiple threads sharing the same ObjectScope is not supported in OpenAccess.

One Thread, Multiple Transactions

This scenario can prove to be beneficial, for example, in case of multi-document interface [MDI] windows. Each window can have its own, separate transactions, allowing you to commit or rollback the work done in one window independently of the other windows.

While using this approach, however, you must be careful not to mix object-networks between two or more transactions.