In the era of. net 1.1, there is no TransactionScope class, so a lot of Transaction processing is handed over to SqlTransaction and SqlConnection. each Transaction is based on each Connection. This design is not very good for transaction behavior that spans multiple assemblies or methods. You need to pass in transactions and database connections as parameters.
After. net 2.0, the emergence of the TransactionScope class greatly simplifies the transaction design. The sample code is as follows:
static void Main(string[] args) { using (TransactionScope ts = new TransactionScope()) { userBLL u = new userBLL(); TeacherBLL t = new TeacherBLL(); u.ADD(); t.ADD(); ts.Complete(); } }
You only need to write the logic block of the transaction package in using (TransactionScope ts = new TransactionScope. From this writing, we can see that TransactionScope implements the IDispose interface. Unless you call the ts. Complete () method. Otherwise, the system will not automatically commit this transaction. If you have not called Complete () after the code runs and exits from this block, the transaction is automatically rolled back. In this transaction block, neither the u. ADD () method nor the t. ADD () method has any transaction class.
TransactionScope is based on the Current thread. In the Current thread, you can call the Transaction. Current Method to view information about the Current Transaction. For more information about how to use TransactionScope, including its member methods and attributes, see MSDN.
The TransactionScope class can be used in nesting mode. To use it in nesting mode, you must specify the transactionscospontion parameter in the nested transaction block. The default value is Required.
The specific meaning of this parameter can refer to the http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscopeoption (v = vs.80). aspx
For example, the following code:
static void Main(string[] args) { using (TransactionScope ts = new TransactionScope()) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); userBLL u = new userBLL(); TeacherBLL t = new TeacherBLL(); u.ADD(); using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Required)) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); t.ADD(); ts2.Complete(); } ts.Complete(); } }
When the TransactionScope's transactionscotion of the nested class is Required, you can see the following results. Their transaction IDs are the same. In addition, the TransactionScope is successful only when both TransactionScope are complete.
650) this. width = 650; "style =" background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; border-top: 0px; border-right: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; "title =" inherit "border =" 0 "alt =" ED8FDA3E241D48B0A90F30A5AC8A9A59 "src =" http://www.bkjia.com/uploads/allimg/131228/155T540Q-0.jpg "height =" 132 "/>
If transactionscospontion is set to RequiresNew, the nested transaction block and the outer transaction block are independent from each other.
static void Main(string[] args) { using (TransactionScope ts = new TransactionScope()) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); userBLL u = new userBLL(); TeacherBLL t = new TeacherBLL(); u.ADD(); using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.RequiresNew)) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); t.ADD(); ts2.Complete(); } ts.Complete(); } }
650) this. width = 650; "style =" background-image: none; border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; "title =" 22D29B0134CD4993B629F085EEBF63D9 "border =" 0 "alt =" 22D29B0134CD4993B629F085EEBF63D9 "src =" http://www.bkjia.com/uploads/allimg/131228/155T53123-1.jpg "height =" 98 "/>
We can see that their transaction IDs are different.
If transactionscospontion is set to Suppress, the transaction in the current block is canceled, which is rarely used.
For database operations between multiple different servers, TransactionScope relies on DTCDistributed Transaction Coordinator to ensure Transaction consistency.
However, for a single server, the TransactionScope mechanism is complicated. It mainly uses the static characteristics of threads. Thread static features ThreadStaticAttribute let CLR know that the access to static Fields marked by it depends on the current thread and is independent of other threads. Since the data in the stored online static field is only visible to the code running in the same thread where the data is stored, you can use this field to pass other data from a method to other methods called by the first method, and there is no need to worry that other threads will destroy its work. TransactionScope stores the current Transaction in the static thread field. When SqlCommand is instantiated later, before this TransactionScope is deleted from the local storage of the thread), The SqlCommand checks the static field of the thread to find the existing Transaction. If yes, it is included in the Transaction. In this way, TransactionScope and SqlCommand can work together, so that developers do not have to pass Transaction display to SqlCommand objects. In fact, the mechanisms used by TransactionScope and SqlCommand are very complex. Specific can refer to the article http://www.microsoft.com/china/MSDN/library/netFramework/netframework/NETMattersSep.mspx? Mfr = true
Professional C #4 and. NET 4 published by Wrox also introduces some usage of TransactionScope.
This article is from the "one blog" blog, please be sure to keep this source http://cnn237111.blog.51cto.com/2359144/1271600