Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Articles
Search: 

TierAdapter Framework: Transactions - Part 1
Ruben Rovira, November 1, 2005
Any database engine, in order to be worthy of receiving this designation, should offer the possibility of handling transactions. The appropriate handling of transactions (among other things) allows us to guarantee the integrity of the stored data. For those with less experience in this subject, I sh...
Summary
Any database engine, in order to be worthy of receiving this designation, should offer the possibility of handling transactions. The appropriate handling of transactions (among other things) allows us to guarantee the integrity of the stored data. For those with less experience in this subject, I shall mention a typical example used in this case, brief and simple.
Description

In the previous issues, we covered the basic points of creating an application using the framework. This issue will be the first of a series about handling transactions.

Remember that you can download the latest version of the TierAdapter and of the complete Demo application, including source code, from our framework's main page at SourceForge.

Introduction to transactions

It is now time to start seeing how the framework allows us to handle transactions. For this purpose, I will describe certain situations we might encounter when we need to open a transaction.

Any database engine, in order to be worthy of receiving this designation, should offer the possibility of handling transactions. The appropriate handling of transactions (among other things) allows us to guarantee the integrity of the stored data. For those with less experience in this subject, I shall mention a typical example used in this case, brief and simple.

Let's assume we have to carry out a money transfer between two bank accounts. The user of the system must specify the date, the amount to be transferred, the bank account where the amount is debited, and finally the bank account where it is credited. Upon confirming the operation, two changes must be stored, the debit and the credit. Now, what would happen if just after storing the debit, and before storing the credit, the operation is interrupted for whatever reason? In case you don't have the possibility of opening a transaction that spans both changes, we might end up having no money in either of the bank accounts, an unpleasant situation if ever there was one. How does a transaction help? The transaction allows us to ask if everything finished OK, and confirm the changes; otherwise, revert them, and leave everything as it was before.

Let's see the representation in pseudo-code:

    InitiateTransaction()
    TRY
        ProcessDebit()
        ProcessCredit()
        ConfirmTransaction()
    CATCH
        RevertTransaction()
    ENDTRY

Usually, database engines automatically place the INSERT, UPDATE and DELETE operations within what is usually called an implicit atomic transaction. If we need to include more than one of these operations in the same transaction, we can manually open another (explicit) transaction that spans them. In this case, we are nesting transactions.

Transactions within a tiered model

In an application designed with a tiered model, as in TierAdapter, the tier that should know how to implement a transaction model is the one that is closest to the database engine.

In our case this is the DataTierAdapter. If we see the code, we will find some methods designed to open transactions, (TransactionBegin), to confirm them (TransactionEnd) and to revert them (TransactionRollback). All this is managed at the level of an entity in the Put method. Now, if it is necessary to span more than one entity within the same transaction, things start to get complicated. In this case, the tier that should know about what entities are spanned by the transaction should be the business tier (BusinessTierAdapter), therefore, it must talk with the data tier in order to ask it to start and close this type of events.

With the tier model, a large variety of possibilities is opened, which we can consider. Depending on the way how the components of the different tiers are distributed, we should implement the transactional model in different ways.

One of the possibilities is to include the different tiers in a single executable (monolithic EXE). Thus, we can interact, without restrictions, between the different tiers.

Something similar happens if we include the data and business tiers of all entities within a single DLL, leaving the user tier and the forms within the executable.

However, it is possible that the data tier and the business tier are in different DLLs, or even, that each entity has its own DLL for its data tier, and another DLL for its business tier. TierAdapter allows us to adopt any of these alternatives. We will see how to do this in the following articles.

Transactions within a disconnected model

Since TierAdapter implements a disconnected model, which doesn't maintain its state, let's see some of the things that must be considered here. Simplifying the concept (quite a lot), we can say that in a disconnected model, for any operation to be done against the database, a conection to the database is opened, the operation is carried out, and the connection is closed again, as quickly as possible. The result of this technique is that we obtain a highly scalable model, since the number of users which have open connections at any one time will be considerably less than with a permanently connected model.

Among other things, transactions have to live within a single connection. Therefore, when we need a single global transaction to span more than one entity, we have to keep the connection open during the operation. We mentioned before that this type of operation, which involves more than one entity, is managed at the business tier, therefore, we should provide it with the required skill to deal with this kind of situation. This applies if the components are in the same EXE or DLL. Otherwise, the only way we can implement the model of distributed transactions is the one offered by COM+, through the Distributed Transaction Coordinator (DTC).

Working with data in different database engines

In TierAdapter, we can handle the possibility of storing data in different databases and even in different database engines. As an example, in the Demo we can see that the entity "User" persists data in the "taSystem" database, which is a native Visual FoxPro database (DBC), wherease the entity "Products" persists in the "NorthWind" database, either in its DBC or SQL-Server versions. It can happen that we need to span a single transaction over two or more entities in different databases; this is another possible scenario which we may have to consider. Here, again, we must use the services of the Distributed Transaction Coordinator (DTC) of COM+.

Different ways of connecting to the database from VFP

If, to the already considerable (for my taste) range of possibilities we add yet other alternatives, perhaps you will feel (as I do) that this is getting too complicated, but unfortunately, any of the possibilities of connecting to different database engines, be it the OLE-DB provider for VFP, the OLE-DB provider for SQL Server, etc., add new variables to the equation, since the possibilities offered by every one of the different providers for different database engines are quite dissimilar.

More information...

You can read more about these subjects in any of these links, from recognized experts:

Conclusion

In this article I tried to enumerate and briefly explain some of the various alternatives which we must consider when we manage transactions in an application. In the next article, we will start seeing every one of the different cases, and how to handle them with the framework.

Ruben Rovira, Desarrollos Independientes
Rubén O. Rovira, (Buenos Aires, Argentina), is a Computer Bachelor. He is devoted to development of custom software for commercial and service companies since 1992. He has used FoxPro and Visual FoxPro as a development tool since version 2.5 (DOS). Nowadays he is an independent Information Systems Consultant, and Lead Developer of the TierAdapter Framework.

Omar Bellio, Soluciones Informáticas
Omar Bellio is a system analyst and independent developer since 1985. He has worked with Fox since its very first version. Today he develops applications for a variety of purposes using Microsoft tools (VFP, VB, .NET PLATFORM, SQL Server, etc.) and also Oracle.
More articles from this author
Ruben Rovira, May 1, 2003
In this article I will talk about ASP.Net mobile controls, and how to use them to puch the functionality of our applications to the domain of mobile devices such as cell phones and PDAs. I will also create a simple web mobile application as an example, using a component developed in VFP8 to sh...
Ruben Rovira, September 1, 2002
In this article we shall see how to use images in forms and reports, in our applications developed with Visual FoxPro. We will also talk about how to optimally organize and save images on disk. Introduction How often have we, as developers in the DOS era, desired to have the possibility t...
Ruben Rovira, June 1, 2005
TierAdapter is an n-tier application development framework developed in Visual FoxPro. Briefly, it implements a hierarchy of classes that makes it possible to quickly develop components for the data access tier, easy to change between the native VFP engine and SQL Server or other engines available t...
Ruben Rovira, July 1, 2005
In this second issue of the series about the framework, we review the Demo application, the way it works and the main features it provides, so in the future issues we can explain how to implement a solution.
Ruben Rovira, September 1, 2005
In this issue, we will continue with the creation of the layers for an entity that includes more than one table, in a header-detail schema; as we shall see, also in this case, the required code is minimal.
Ruben Rovira, August 1, 2005
In this new issue, we will show the steps to follow to develop an application from zero. Also, as mentioned at the end of the previous issue, we will demonstrate that very little code has to be written in order for everything to work correctly.
Ruben Rovira, December 1, 2005
This time, we will briefly make a detour from the transactions (until the next issue), and look at different ways in which the framework allows us to distribute application components. This will serve as a basis, so that we can later analyze how to use transactions in every one of these cases.
Ruben Rovira, October 1, 2005
The basic idea is to place, within a Try/Catch block, a call to any process that might generate an exception (is there any process that can't?). When the exception is generated, it will be trapped by the Catch command, and processed differently, depending on the tier where it happens. The tier which...
Ruben Rovira, April 1, 2003
In the following paragraphs I shall try to summarize what web services are and later, step by step, I'll explain how to create a web service usign VFP8. This web service will be used in the third part of this note where, always from VFP8, we'll develop a small application that will consume the ...