Browse DevX
Sign up for e-mail newsletters from DevX


Build a Framework for Managing Distributed Transactions in Three-tier Applications : Page 4

For many transactional applications in .NET, you can avoid the overhead of using Enterprise Services and simply mimic the simple transactional style of COM+ applications by using a DistributedTransaction object that wraps an ADO.NET Transaction object.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Making Business-to-business Calls
Sometimes you need to implement distributed transactions involving different business layer methods in addition to DAL methods. If all the operations execute inside different transactions (where the business layer code is set to the RequiresNewTransaction COM+ pattern), everything works according to the sequence already shown. However, if you need to execute multiple operations inside the same transaction's context (the RequiresTransaction pattern), you must provide two overloads for the business layer methods involved. The first accepts a DistributedTransaction object as an input parameter; the second does not. Otherwise, all the other parameters are identical. In this scenario, the overload that requires the DistributedTransaction parameter is a "secondary" method that implements a local business operation, acting as a server for the "primary" methods that start transactions and define business operations at a higher level.

The overload that doesn't take a DistributedTransaction looks like this:

' -- First overload without transaction Public Sub DoSomething (ByVal input as Object) ' [...] Validates parameters ' -- Defines transactional context for business operations Dim tr As DistribuitedTransaction Try ' -- starts transaction tr = New Transaction(_connstring) ' - Calls business method that requires transaction DoSomething (input, tr) ' [...] If required, can also call other business or ' data methods passing tr as context ' -- commits transaction tr.Commit() Catch ex As Exception ' -- Rolls back Transaction tr.Abort() ' [...] Logs error Throw ' some user defined error... Finally ' -- Releases transaction tr.Dispose() End Try End Sub

Here's the overload that accepts a DistributedTransaction.

' -- Second overload with transaction Friend Sub DoSomething (ByVal input as Object, ByVal tr As Transaction) '— [...] checks parameter Try Dim myData As New DAL myData.DoSomething (input, tr) Catch ex As Exception ' -- disable transaction's commit tr.DisableCommit() ' [...] Logs error Throw End Try End Sub

In C#:

// First overload without transaction public void DoSomething(object input) { // [...] Validates parameters // Defines transactional context for business operations DistribuitedTransaction tr; try { // starts transaction tr = new Transaction(_connstring); // Calls business method that requires transaction DoSomething(input, tr); // [...] If required, can also call other business or // data methods passing tr as context // commits transaction tr.Commit(); } catch (Exception ex) { // Rolls back Transaction tr.Abort(); // [...] Logs error throw; } finally { // Releases transaction tr.Dispose(); } } // Second overload with transaction internal void DoSomething(object input, Transaction tr) { // [...] checks parameter try { DAL myData = new DAL(); myData.DoSomething(input, tr); } catch (Exception ex) { // disable transaction's commit tr.DisableCommit(); throw; } }

The first method creates the transaction and calls the overload that requires it as input. This method works exactly as described earlier for simpler scenarios, except that it uses the passed-in DistributedTransaction object instead of creating a new one. Note its error handler, which acts like error handlers typically found in DAL methods. In other words, it calls DisableCommit rather than rolling back the transaction, because this particular business layer method has a secondary role, just as DAL methods usually do. It's usually better to define such support methods as Private or Friend, so they can't be exposed outside the project; however, sometimes the assembly structure will require you to distribute the business operation in such a way that you must define all overloads as Public. In this particular case, the Façade layer's components expose and map only business methods that don't require transactions.

With this last structure in place, you have in fact replicated the NewTransaction and RequiresNewTransaction COM+ patterns used in a declarative way in VB6 and other COM-based languages. You obviously still need code to implement the various layers, but now you can write that code in a clear linear fashion that's much simpler than using only the ADO.NET base objects.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date