Friday, August 27, 2004

Just SetAbort didn't work

I was stumped when I tried to setup a classical transaction rollback example. All I did was creating an account A class and tried to manipulate the static variable Balance. SetAbort did not work, I mean, it did not bring back the balance to its initial value.

Do I need to take care something in the resource management front?

Tuesday, July 13, 2004

Distributed Transaction

So far, we were considering cases where the transaction scope was limited on a single database. If we take the example of account A and B, our implicit assumption was that the accounts are managed on a single database, say, a specific bank's database. In reality, we have multiple banks in the market, and for good reasons, account A and B can belong to two different banks. However, such transactions like transferring 500 bucks from account A to account B will still be a valid business requirement.

So, now, our problem specification has been changed to "log changes to both databases, or roll back from both". Such a transaction is commonly defined as Distributed Transaction, as the scope of the transaction is now spread on more than one databases.

As long as the scope of a transaction remains within a single database, transaction can be controlled using Transaction Control SQL statements such as Commit or Rollback. When the transaction spreads across databases, such database level controls can no longer be enforced. To manage such distributed transactions we need a Distributed Transaction Manager, a generation ahead of Transaction Manager.

Monday, July 12, 2004

Managing Transactions Across Components

Now, we have got specific components for generalized functions, we need to define our sample transaction of transferring 500 bucks from account A to account B. For simplicity, let's develop two components: one operating on account A, say CompA and the other on account B, say CompB. We will be having a third component to implement our transaction, i.e. transferring 500 bucks from account A to account B.

As we can see both of CompA and CompB do database operations, and the current scope of the sample transaction will allow them to do so. However, none of these two will be able to finalize the database updates, since one is dependent on the other. Which means, at any point of time, if any of the operations fail, the entire process needs to be rolled back and this needs to be done across CompA and CompB.

There comes the Transaction Manager, which will take care of such a complex activity of committing the whole operation or rolling back everything. Transaction Manager makes the implementation work pretty simple, i.e. in terms of writing codes. In the example above, it will be implemented by a set of two/three lines of codes in the third component, i.e. the component implementing the business logic.

Over the period of time Transaction Managers have become more and more powerful and now they are capable of handling distributed transactions as well, thus rechristened them as Distributed Transaction Coordinator.

Thursday, July 08, 2004

Classes, Objects, and Components

We all know about classes, and its features. We know how we design and develop methods and properties, and their respective access modifiers. Over the period of time, the definition of class gets mature and consistent across the programming languages to implement. The classes, at runtime, get instantiated into objects and behave according to their respective states.

When we instantiate a class, we get an object. An object represents a specific state, which includes the values of the properties, and also represents the inter-dependency with other objects. Classes provide a good degree of encapsulation to represent the abstractions of the real world entities. However, classes pose a few limitations while going for large application development. While classes offer the facility to provide contractually defined interfaces, it has little provision to offer language independent interfaces through which the it can be accessed. It also do not offer very good independent deployment scope.

Thus comes the conecept of component which satisfies everything that is there for a class, and something extra. This "extra" makes a component to be deployable independently, as well as offers composition by third parties. An application built using components are said to be more robust, more flexible, and reduces the development time. It is said to be robust since it implements the services of the real world entities rather than just the real world entities. It is said to be flexible since it offers the third party language neutral composition. While classes take the mathematical modelling of the approach to the software, components takes the engineering approach. Thus the component based architecture offers better time to implementation.

Like class, a component, when instantiated, creates an object. However, there is a little difference with the object created out of a component with the object created out of a class. Components need containers.

Tuesday, July 06, 2004

Grouping Functions into Components

Once we understand the needs for having functions for generalized activities, we can analyze the application requirements to identify such functions. After carefully going through their base intents, we will find quite a few features that are common among them. These commonality can be based on generic functionality as well as it can be based on the application functions. If we go by the activities of the account transfer in details, we will find a few such characteristics on which are spread across the functions, such as:

1. Numeric and Logical Operations (addition between numbers, subtraction between numbers, identifying the greater number out of two numbers)
2. Making query into the accounts database to obtain the balance (will be required for both validation, addition, and sutraction)
3. Updating the accounts database with modified balances (will be required for both log activities)

If we go through each of these, #1 is a set of generic number crunchers. #2 requires a database connection to make queries. #3, on the other hand, requires database connection, as well as proper access to update and commit data.
Based on such analysis the required functions and methods can be now grouped into three groups, where each of these group will be having some properties to be applied upon all functions within this group.

Implementation of such groups are done through components.

Creating Functions for Generalized Activities

So far, we have seen how a set of activities constitute a single transaction. The underlying intent of breaking down a transaction into granular level of activities is to promote the scope of reusability. By reusability, I mean to say the reusability of generic functions. More granularity will ensure more similarity towards a generic functions, thus more opportunity to use those.

Let's take the example of money transfer between account A and B as I mentioned before. If we go by the set of five activities, each one represents an opportunity to reuse a generic function. Let's consider the Activity #1: Check that account balance of A is greater than or equal to 500. This one can be implemented using a function similar to

bool HasSufficientBalance (string accountID, long balanceRequirement)

The parameters are accountID to make a query into the accounts database to get the balance, and the balanceRequirement is to measure whether the condition satisfies or not. If such a function does not exist the objective should be to develop such a function which can be used to implement the current requirement as well as can be used for future application development.

Having such functions developed and ready for reuse, we can easily reuse them by calling from a requirement specific program, organize and execute those in the required sequence, and get the desired output, or complete the specified transaction.

There comes the benefits of having functions for generalized activities, where each function can be idenfied with a generic intent to perform a single of task.

Monday, July 05, 2004

What is a Transaction?

The term Transaction is used in different functional areas to mean different functional aspect, albeit with a significant degree of similarity. As a result, the definitions vary depending upon the perspective from which it is looked upon.
In terms of software applications, I have found a few definitions/explanations of a transaction and summed up to something as follows:


A transaction denotes a smallest possible set of activities to complete a unit of work pertaining to the functional requirements for that particular application.

Let's take an example (this is one those heavily used example to explain transaction, and I like this very much). There is an account A and an account B, each containing 1000 bucks. Now, a transaction has been requested to transfer 500 bucks from account A to account B. From functional point of view, this transfer denotes a transaction. From application point of view, this denotes a set of activities which are to be performed as a unit of work. The activities are:

1. Deduct 500 bucks from account A.
2. Add 500 bucks into account B.
3. Log the final balance of account A as 500.
4. Log the final balance of account B as 1500.

All these four activities must be completed successfully to ensure that the transaction gets successfully completed. If any one of these fails, all earlier activities have to be rolled back to bring the states of the accounts into their originial ones, thus denoting the transaction to be a failed/incomplete one. So in such an example, the set of these four activities are considered to be a transaction.

Depending upon the functional requirement, number of activities can vary. As example, the transaction above, may include some validations to ensure that the account balance does not fall below zero. That way, one more additional activity would get added prior to activity #1, and the transaction would be a set of five activities:

1. Check that account balance of A is greater than or equal to 500.
2. Deduct 500 bucks from account A.
3. Add 500 bucks into account B.
4. Log the final balance of account A as 500.
5. Log the final balance of account B as 1500.

Each of these activities can be implemented using a specific programming block called functions or methods.

Friday, July 02, 2004

Key Features of an Application Server

Before getting into the details of what COM+ offers, let's try to understand the basic features that an application server should offer. I went through a few writings here and there, and finally summed up to three:

1. Transaction Management (including distributed transaction management)
2. Resource Pooling
3. Messaging

And, of course, there are many more essential and nice-to-have features provided by several application server products on various platforms.

Managing Transactions

I found an assembly doing significant amount of updates and inserts into the database while not being registered into COM+. It is just registered into GAC and doing everything. In terms of managing transactions, is this enough? Need to find out more.