TransactionScope is a new namespace added in. net Framework2.0. Its purpose is to provide a "lightweight" thing for database access. Before use, you must add a reference to System. Transactions. dll. First, we will introduce several simple parameters.
TransactionScopeOptions |
Description |
Required |
If a transaction already exists, the transaction scope will be added to the existing transaction. Otherwise, it will create its own transaction. |
RequiresNew |
This transaction scope will create your own transactions. |
Suppress |
If the transaction is within the scope of the current active transaction, the transaction scope will neither join the ambient transaction nor create your own transaction. This option can be used when some code needs to be left outside the transaction. |
You can check whether the Transaction scope exists at any location of the Code. The specific method is to view the System. Transactions. Transaction. Current attribute. If this attribute is "null", the current transaction does not exist.
To change the default settings of the TransactionScope class, you can create a TransactionOptions object and set the isolation level and transaction timeout time on the TransactionScope object. The TransactionOptions class has an IsolationLevel attribute, which can be used to change the isolation level, for example, from the default Serializable to ReadCommitted, you can even change the Snapshot level introduced by SQL Server 2005. (Remember, isolation level is just a suggestion. Most database engines try to use the suggested isolation level, but may also choose another level .) In addition, the TransactionOptions class also has a TimeOut attribute, which can be used to change the TimeOut time (1 minute by default ).
TransactionOptions opt = new TransactionOptions ();
// Set TransactionOptions
Opt. IsolationLevel = IsolationLevel. ReadCommitted;
// Set the timeout interval to 2 minutes. The default value is 60 seconds.
Opt. Timeout = new TimeSpan (0, 2, 0 );
When using
Using (TransactionScope sCope = new TransactionScope (transactionscospontion. RequiresNew, opt ))
Others are the same as default
The following is a simple demo that requires only a few lines of code to be added. This model can handle exceptions and will be cleaned up after execution. In addition, it can also manage command submission or rollback
1. TransactionScope is within the scope of a transaction
In app. config
<ConnectionStrings>
<Add name = "myCon" connectionString = "Data Source =.; uid = sa; pwd = sa; database = B2C3; Asynchronous Processing = true"/>
<Add name = "myCon2" connectionString = "Data Source =.; uid = sa; pwd = sa; database = B2C; Asynchronous Processing = true"/>
<Add name = "myCon3" connectionString = "Data Source =.; uid = sa; pwd = sa; database = demo; Asynchronous Processing = true"/>
<Add name = "myCon4" connectionString = "Data Source =.; uid = sa; pwd = sa; database = News; Asynchronous Processing = true"/>
</ConnectionStrings>
Static void Main (string [] args)
{
String constr = ConfigurationManager. ConnectionStrings ["myCon"]. ConnectionString;
String constr2 = ConfigurationManager. ConnectionStrings ["myCon2"]. ConnectionString;
String SQL = "insert into [Tuser] (username, pwd, age) values ('news socpe test', 'bbb', 10 )";
# Region transactions of different databases
Using (TransactionScope sope = new TransactionScope ())
{
Using (SqlConnection con = new SqlConnection (constr ))
{
Using (SqlCommand cmd = new SqlCommand (SQL, con ))
{
Con. Open ();
Int a = cmd. ExecuteNonQuery ();
Console. WriteLine ();
}
}
Using (SqlConnection con = new SqlConnection (constr2 ))
{
Using (SqlCommand cmd = new SqlCommand (SQL, con ))
{
Con. Open ();
Int B = cmd. ExecuteNonQuery ();
Console. WriteLine (B );
}
}
AddOtherUser ();
Sope. Complete ();
}
# Endregion
Sope. Complete (); is a sign. Transactions are submitted only when all tasks are run.
2. nested call transactions
Static void Main (string [] args)
{
String constr = ConfigurationManager. ConnectionStrings ["myCon"]. ConnectionString;
String constr2 = ConfigurationManager. ConnectionStrings ["myCon2"]. ConnectionString;
String SQL = "insert into [Tuser] (username, pwd, age) values ('news socpe test', 'bbb', 10 )";
# Region transactions of different databases
Using (TransactionScope sope = new TransactionScope (transactionscospontion. Required ))
{
Using (SqlConnection con = new SqlConnection (constr ))
{
Using (SqlCommand cmd = new SqlCommand (SQL, con ))
{
Con. Open ();
Int a = cmd. ExecuteNonQuery ();
Console. WriteLine ();
}
}
Using (SqlConnection con = new SqlConnection (constr2 ))
{
Using (SqlCommand cmd = new SqlCommand (SQL, con ))
{
Con. Open ();
Int B = cmd. ExecuteNonQuery ();
Console. WriteLine (B );
}
}
AddOtherUser ();
Sope. Complete ();
}
# Endregion
}
Private static void addOtherUser ()
{
String constr3 = ConfigurationManager. ConnectionStrings ["myCon3"]. ConnectionString;
String constr4 = ConfigurationManager. ConnectionStrings ["myCon4"]. ConnectionString;
String sql1 = "insert into [hr_user] (username, password) values ('news socpe test', 'bbb ')";
String sql2 = "insert into [Users] (username, userpwd) values ('news socpe test', 'bbb ')";
// RequiresNew the transaction scope will create your own transaction.
Using (TransactionScope sope = new TransactionScope (transactionscospontion. RequiresNew ))
{
Using (SqlConnection con = new SqlConnection (constr3 ))
{
Using (SqlCommand cmd = new SqlCommand (sql1, con ))
{
Con. Open ();
Int a = cmd. ExecuteNonQuery ();
Console. WriteLine ();
}
}
Using (SqlConnection con = new SqlConnection (constr4 ))
{
Using (SqlCommand cmd = new SqlCommand (sql2, con ))
{
Con. Open ();
Int B = cmd. ExecuteNonQuery ();
Console. WriteLine (B );
}
}
Sope. Complete ();
}
}
Summary:
Now we know that database operations in TransactionScope are actually involved in this process.Environment transactionIt is understood as an automatically created SqlTransaction, and database operations nested in the TransactionScope will be added to this environment transaction (TransactionScope generated with transactionscospontion. Required as the parameter ).
It is also known that the Complete method will not commit the transaction after execution, but it only indicates that the previous actions meet the requirements. It is only a confirmation. If you do not execute this method, the transaction cannot be completed. However, after the Complete method is executed in the outermost TransactionScope, the transaction is actually committed only when the using block is left. Therefore, TransactionScope can be nested.
The Transaction class has a static attribute Current, which can be accessed before the Complete method in TransactionScope is executed. The returned value is an environmental Transaction.
However, it is very important that the transaction enters and exits quickly because the transaction locks valuable resources. The best practice requires that we create a transaction before using it, and quickly open the connection and execute Action Query before executing the command on it ), complete and release transactions as quickly as possible. During transaction execution, you should also avoid executing any unnecessary database-independent code, which can prevent resources from being locked for a long time without any doubt.
}