Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Implementing Concurrency Control?

Status
Not open for further replies.

steverbs

Programmer
Jul 17, 2003
253
GB
Hi all.

We are considering developing an application that will potentially be used by up to 30 users at a time and so I have got to thinking about concurrency. I understand the concepts behind concurrency control and I feel that our best option is the Optimistic Offline Lock, but I have not found a single source that explains exactly HOW this is implemented. At the moment, my OR Mpping layer (devloped in .NET) uses the application cache to check for objects before loading them (an identity map as Fowler calls it), is this where I perform the concurrency control? If not, then how do I implement it?

Can someone please help me with this. I have been looking for information about how to implement concurrency control without any success for some time now and I am starting to get a little concerned.

Regards.

Stephen.
 
Ok, I have found some reading material and have been reading up on how to implement an Optimistic Offline Lock for my OR Mapper by adding a version number field to the db and the class and comparing the stored and cached object's data version. However, while I can see this working for an individual Object, what happens if I am persisting several related Objects back to the database and one of the transacations fail? For example:

objCustomer.myDepartment = objDepartment
objCustomer.myDepartment.persist() -- Fails
objCustomer.persist() -- Succedes

Now I am left with corrupt data as the objDepartment object has not been stored, but the objCustomer object thinks it has myDepartment as a valid property.

How do I prevent this from happening?

Regards.

Stephen.
 
using locks depend on ur application
if u are using text file open them in exclusive mode while writing. so no concurrency problem ..
if u are using database make insert,update,delete inside
begin and end transation.. use unique index to avoid duplicate records etc ...
 
Cheers for the reply. The problem I am having is that I am not able to begin all of the required SQL queries within a transaction. Lets say I have ClassA and ClassB and that they are related. Both Classes have a persist Method that uses SQL Commands to persist their data to an SQL Server database. I would somehow need to start the SQL transaction outside of the instances of these Classes when calling their perist methods:

objClassA = new ClassA
objClassB = new ClassB
objClassB.myClassA = objClassA
objClassA.persist()
objClassB.persist()

Now, if there were a concurrency violation and the SQL statement within objClassA.persist() failed, I would need to not only roll-back that SQL command, but also the SQL command within objClassB.persist() method, which is impossible using SQL Transactions alone.

However, I have found a work-around that seems to be doing the trick. I have created my own transaction Class, whose sole-instance sits in the Session Object and, making use of the above example, is called like so:

objTransaction = new AppTransaction

objTransaction.beginTransaction()

objClassA = new ClassA
objClassB = new ClassB
objClassB.myClassA = objClassA
objClassA.persist()
objClassB.persist()

objTransaction.commitTransaction()

The AppTransaction Object begins the SQL Connection, Command and Transaction and within the persist() methods is some code that communicates with the transaction instance and lets it know if there are any errors. When the commitTransaction() method is called it checks for errors and if any are found it will roll back the SQL Transaction.

I don't know how reliable this is, but gets the job done. If there are any better

Regards.

Stephen.
 
Stephen, have you looked at the LLBLGen (open-source version) code generator?
It's worth looking at the architecture it produces, and it might give you some clues as to how to handle these transactions. It (the LLBLGen architecture) has some weak points and I wouldn't necessarily reccomend using it, but the way connections and transactions are handled are pretty neat. Basically what he does is have each entity class inherit from a base class (DBInterationBase) that handles the connections/transactions through the use of a "ConnectionProvider" class, which can start it's own transcations or participate in an existing transaction. So what you end up with is something like
Code:
ConnectionProvider con = new ConnectionProvider();
classAInstance.ConnectionProvider = con;
classBInstance.ConnectionProvider = con;
try{
 con.OpenConnection();
 con.BeginTransaction();
 
 classAInstance.Insert();
 classBInstance.Insert();
 con.CommitTransaction();
}catch{
 con.RollbackTransaction();
}finally{
 con.CloseConnection();
}

So it's fairly easy to use, and it's very solid.

Now, I am hoping that all of this is going to go away with .NET 2.0 and ObjectSpaces.....;)
 
Cheers. On the surface, that looks very similar to how I have solved the problem.

While it will be nice to see Microsoft help those of us who want to use the OO capabilities of .NET, I will be gutted at having nearly completed my own OR Mapping Layer when ObjectSpaces is released.

Anywho, I'll take a look at LLBL Gen to see what it offers. I've already looked at Pragmatier and Raptier, but they both seemed very long-winded and unflexible.

Regards.

Stephen.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top