Using DistributedTransaction in the DAL and Business Layers
Now that you have a distributed transaction object, you can use it while implementing client code.
The DAL's methods should
always receive a DistributedTransaction object as an input parameter, already instantiated and ready to work. In general you can avoid inserting other explicit code to manage the distributed transaction (as in COM+); for example, a DAL method might look like this:
Public Sub SaveSomething(byVal Input as Object,
ByVal transaction As DistributedTransaction)
' -- [...] Saves data using transaction.SqlTransaction
' to send SQL commands
End sub
In C#:
public void SaveSomething(object Input,
DistributedTransaction transaction) {
// [...] Saves data using transaction.SqlTransaction
// to send SQL commands
}
To handle internal errors, use the
DisableCommit method defined earlier, in the same way you would have previously used it in COM+. For example:
Public Sub SaveSomething(byVal Input as Object,
ByVal transaction As DistribuitedTransaction)
Try
' -- check parameters
If transaction Is Nothing Then Throw New
ArgumentNullException("transaction cannot be null")
If input Is Nothing Then Exit Sub
' -- [...] Prepares parameters and executes command
' on transaction.SqlTransaction
Catch ex As Exception
' -- disables transaction
transaction.DisableCommit()
' -- [...] Logs detailed error
Throw
End Try
End Sub
In C#:
public void SaveSomething(object Input,
DistributedTransaction transaction){
try {
// check parameters
if (transaction == null) {
throw new ArgumentNullException(
"transaction cannot be null");
}
// -- [...] Prepares parameters and executes command on
// transaction.SqlTransaction
}
catch (Exception ex) {
// disables transaction
transaction.DisableCommit();
// [...] Logs detailed error
throw;
}
}
When an error occurs, the method disables the transaction (without directly calling
SetAbort, so other methods that use the transaction can continue to work, reproducing the typical COM+ pattern) and propagates one exception that the client may handle. When the method needs to interact with the database, it can use the ADO.NET transaction object exposed by the
DistributedTransaction.SqlTransaction property, without creating new connections.
Inside the Business Layer
To start a transaction, business layer methods should instantiate a DistributedTransaction object, pass it to DAL methods, handle exceptions, and finally, commit or roll back the transaction.
The important code of such methods is the part that handles the operation's result, committing or rolling back the transaction. It also needs to ensure that resources used by DistributedTransaction object get released. Typical code would follow the pattern shown below.
Public Sub DoSomething (ByVal input as Object)
' [...] Validates parameters
' -- Defines transactional context for business operations
Dim tr As DistribuitedTransaction
Try
' -- instances DAL
Dim myData As New DAL
' -- starts transaction
tr = New Transaction(_connstring)
' [...] Calls DAL method
' -- commits transaction
tr.Commit()
Catch ex As Exception
' -- Rollback Transaction
tr.Abort()
' [...] Logs error
Throw ' some user defined error...
Finally
' -- Releases transaction
tr.Dispose()
End Try
End Sub
In C#:
public void DoSomething(object input) {
// [...] Validates parameters
// Defines transactional context for business operations
DistribuitedTransaction tr;
try {
// instances DAL
DAL myData = new DAL();
// starts transaction
tr = new Transaction(_connstring);
// [...] Calls DAL method
// commits transaction
tr.Commit();
}
catch (Exception ex) {
// Rolls back Transaction
tr.Abort();
throw;
}
finally {
// Releases transaction
tr.Dispose();
}
}