这是 TransactionSope 的正确用法吗?
Is this correct usage of TransactionSope?
我决定尝试使用 TransactionScope
,而不是 SqlTransaction
class。
以下是我的代码,包裹在TransactionScope
:
using (var transaction = new System.Transactions.TransactionScope())
{
using (MySqlCommand cmd = new MySqlCommand(sql, connection))
{
if (listParameters != null && listParameters.Count > 0)
{
foreach (string currentKey in listParameters.Keys)
{
cmd.Parameters.Add(new MySqlParameter(currentKey, GetDictionaryValue(listParameters, currentKey)));
}
}
using (MySqlDataReader reader = cmd.ExecuteReader())
{
dtResults.Load(reader);
}
}
transaction.Complete();
}
代码有效,但是我在任何时候都没有将 MySqlCommand
cmd
对象与事务绑定。这是个问题吗?
不,这不是正确的用法。
正确的用法是在创建TransactionScope之后再创建连接。然后连接将检测环境 TransactionScope 并自行登记。
using (var transaction = new System.Transactions.TransactionScope())
{
using (var connection = new MySqlConnection())
{
...
}
}
如果您在范围之前创建连接,则该连接将超出该范围,即使您在创建范围之后创建命令也是如此。
另请注意,TransactionScope 默认为 Serializable 隔离级别。这是最安全的级别,也是并发最少的级别。你经常想明确设置一个更常见的隔离级别:
using (var transaction = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
{
}
我决定尝试使用 TransactionScope
,而不是 SqlTransaction
class。
以下是我的代码,包裹在TransactionScope
:
using (var transaction = new System.Transactions.TransactionScope())
{
using (MySqlCommand cmd = new MySqlCommand(sql, connection))
{
if (listParameters != null && listParameters.Count > 0)
{
foreach (string currentKey in listParameters.Keys)
{
cmd.Parameters.Add(new MySqlParameter(currentKey, GetDictionaryValue(listParameters, currentKey)));
}
}
using (MySqlDataReader reader = cmd.ExecuteReader())
{
dtResults.Load(reader);
}
}
transaction.Complete();
}
代码有效,但是我在任何时候都没有将 MySqlCommand
cmd
对象与事务绑定。这是个问题吗?
不,这不是正确的用法。
正确的用法是在创建TransactionScope之后再创建连接。然后连接将检测环境 TransactionScope 并自行登记。
using (var transaction = new System.Transactions.TransactionScope())
{
using (var connection = new MySqlConnection())
{
...
}
}
如果您在范围之前创建连接,则该连接将超出该范围,即使您在创建范围之后创建命令也是如此。
另请注意,TransactionScope 默认为 Serializable 隔离级别。这是最安全的级别,也是并发最少的级别。你经常想明确设置一个更常见的隔离级别:
using (var transaction = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
{
}