Misuse of the TransactionScope Complete Method

Source: Internet
Author: User

Because no better method can be found and the project does not adopt any third-party framework (such as nhib.pdf), I have been using TransactionScope to manage business transactions at the business layer, microsoft translates it into a range of transactions, it can be used to implement the implicit transactions within the scope, the specific use of this article will not talk about more, you can refer to MSDN: http://msdn.microsoft.com/zh-cn/library/ms172152.aspx

Today, I encountered A problem: Introduce TransactionScope in method A, call Method B in method A, and introduce TransactionScope (TransactionScope can be nested) in method B ), many of my codes are written in this way:

Code
1 public OperationResult ()
2 {
3 OperationResult result = new OperationResult ();
4 int errorCount = 0;
5
6 using (TransactionScope tx = new TransactionScope ())
7 {
8 try
9 {
10 // TODO
11}
12 catch
13 {
14 errorCount ++;
15}
16 if (B (). Result! = ResultInfo. Operation successful)
17 {
18 errorCount ++;
19}
20 if (C (). Result! = ResultInfo. The operation is successful) // If B fails at this time, the TransactionScope in Calling C will encounter the "transaction terminated" Exception
21 {
22 errorCount ++;
23}
24 if (errorCount = 0)
25 {
26 result. Result = ResultInfo. The operation is successful;
27 tx. Complete (); // I wrote all the complete here
28}
29}
30
31 return result;
32}
33
34 public OperationResult B ()
35 {
36 OperationResult result = new OperationResult ();
37
38 using (TransactionScope tx = new TransactionScope ())
39 {
40 try
41 {
42 // TODO
43 tx. Complete ();
44}
45 catch
46 {
47 result. Result = ResultInfo. the operation failed. // now let's assume the catch is complete. In this case, TransactionScope in B does not call complete.
48}
49}
50}
51
52 public OperationResult C ()
53 {
54 OperationResult result = new OperationResult ();
55
56 // when Method B fails, that is, when Method B does not execute the complete, an exception "transaction terminated" will occur when the call is made"
57 using (TransactionScope tx = new TransactionScope ())
58 {
59 //
60}
61}
In this way, if any method in B is incorrectly executed, the complete is not executed. In this way, the Environment transaction is terminated directly within the called function. If the following code references TransactionScope, A "transaction terminated" exception is thrown.


I always thought that the complete should be placed in the "correct business logic". If the program is not correctly executed, do not execute the complete. It will automatically roll back. I now know that my idea is very gray and wrong. It will roll back and it will terminate the dual directly. The following is an explanation of MSDN:

 

When you are satisfied that all operations in the range have been successfully completed, you should call this method only once to notify the transaction manager that the statuses of all resources are consistent, you can also submit the transaction. It is a good practice to use this call as the last statement in the using block.

For more information about how to use this method, see implement implicit transaction theme using transaction scope.

Failure to call this method will abort the transaction because the Transaction Manager interprets this as a system fault or raises an exception in the transaction scope. However, you should also note that calling this method does not guarantee the transaction commit. It is just a way to notify the Transaction Manager of the status. After this method is called, The Environment transaction cannot be accessed through the Current attribute. If you try this method, an exception is thrown.

If a TransactionScope object creates a transaction, the actual commit between resource managers takes place in the End Using statement. If it does not create a transaction, it is committed whenever the owner of the CommittableTransaction object calls Commit. At that time, the transaction manager will call the resource manager and notify them to submit or roll back based on whether this method is called on the TransactionScope object.

Looking at this sentence, if you fail to call this method, the transaction will be aborted. That is to say, if you do not call the complete method, the transaction will be terminated directly, "because the Transaction Manager interprets this as a system fault or an exception is thrown in the transaction scope," I understand TransactionScope, it can guarantee your implicit transactions within its lifecycle. No matter what database operations you perform, it will organize these operations into an environment transaction for you, if a problem occurs at any stage, the entire transaction will be implicitly rolled back. complete does not tell the Transaction Manager to start committing immediately, but only notifies the Transaction Manager that my operation status has been completed, I used to take it as dbtransaction, and only submit after successful execution, but not rollback. complete just says, "You can submit after my job is finished ", if you do not call this method within its lifecycle, the transaction will be aborted. This is like Method B I wrote above. When you try again (using a new TransactionScope, you will encounter the "transaction terminated" error. Therefore, I will modify the Code as follows:

Code
1 public OperationResult ()
2 {
3 OperationResult result = new OperationResult ();
4 // int errorCount = 0; this variable can be thrown
5
6 using (TransactionScope tx = new TransactionScope ())
7 {
8 try
9 {
10 // TODO
11}
12 catch
13 {
14 return result;
15}
16 if (B (). Result! = ResultInfo. Operation successful)
17 {
18 return result;
19}
20 if (C (). Result! = ResultInfo. The operation is successful) // If B fails at this time, the TransactionScope in Calling C will encounter the "transaction terminated" Exception
21 {
22 return result;
23}
24 result. Result = ResultInfo. The operation is successful;
25 tx. Complete (); // now all are placed at the end of the TransactionScope Lifecycle
26}
27
28 return result;
29}
30
31 public OperationResult B ()
32 {
33 OperationResult result = new OperationResult ();

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.