views:

847

answers:

5
+1  Q: 

Transaction Scope

How does the transaction scope work? How does it know when there is another context being used already and how might I implement another kind of scope in my code.

I'm primarily a vb.net developer but I can read the c# if you write in that.

In case the above was too vague:

I understand what system.transactions does and how to use it. What I want to know is how to create something similar, my own library that I can wrap around some code that can handle it in the same manner as the system.transactions scope does. I plan on using this with a caching model and it would greatly enhance it. I'm looking for details on how transaction scope knows for example that there is a parent scope and so it can attach to it and such, or that a commit then needs to take place at a higher level or in a higher contact.

For example, if I have the following

using scope1 as new system.transactions.scope
    using scope2 as new system.transactions.scope
        using scope3 as new system.transactions.scope
             scope3.commit
        end using
        scope2.commit
    end using
end using

Scope1 will not commit and so neither will scope2 or scope3 since the parent to them all is the context of scope1. I'd like to be able to set this up with my own libraries.

A: 

I'll take a stab, but I'm not 100% sure of the question.

Transactions, in terms of databases, tend to have scopes. This indicates a coverage of the amount of data that is being changed within the transaction. They are implemented in the database server, and cannot be changed "in code". Each database server will have its own implementation, and each server (oracle, MSSQL, MySQL) will have their own behaviours.

Generally a transaction will lock out any other connections from reading data that it is in the middle of modifying. The scope of the transaction will start as small as possible, and then expand as the amount of data being changed grows. It's in the database's best interest to lock as little data as possible, and it does this by:

  • Locking a single column in a single row of data
  • then locking a single row of data
  • then locking a page of data (8096 bytes perhaps?)
  • then locking an entire table of data

If your update modifies multiple rows of data, the transaction scope will expand to a page size (custom for each server), or to lock the entire table. Some database servers will allow other connections to read the table as it was before the update while the transaction is in progress, and other database servers will block any selects on data until the transaction is committed.

Basically the deal is that you cannot modify the way the server has been implemented, and transaction scope isn't something you should worry too much about. Just be sure to have transactions only used around succinct updates that are dependant on each other. I typically don't use transactions. But then again, I'm not working with bank accounts or any other referentially critical systems.

Hope this helps!

Kieveli
A: 

Your question is quite ambiguous so hard to know what you are actually asking about and seeking as an answer but perhaps this will help?

http://www.codeproject.com/KB/dotnet/TransactionScope20.aspx

duncan
+5  A: 

I suggest the article Introducing System.Transactions by Juval Lowy

Preet Sangha
A: 

I think that I've found a solution to reproducing the scope behaviour. I'll post the info shortly but basically it involves implementing idisposable with a static value to track nested instances of the object. In order to connect it to a cache provider I plan on using an array list of the cached object so then run some sort of clean up when the object is disposed of. I think that I also know how to deal with threading issues but I'm still working through the logistics. When I'm done I'll release the code so that it can be deployed on top of velocity in order to hand some of the current challenges that I am facing.

Middletone
A: 

I don't know how System.Transactions works internally but you can achieve this using thread-local memory. In .NET the ThreadStatic attribute will give you this. Declare your scope context somewhere like this:

[ThreadStatic]
private static Context scopeContextThingy;

and there'll be exactly one scopeContextThingy per thread. Then if scopeContextThingy == null, you're the parent and should create a new context. Otherwise, you're a nested scope.

MandyK