我们在使用 TransactionScope 时遇到问题。TransactionScope 为我们提供了很好的灵活性,可以在我们的数据访问层中使用事务。通过这种方式,我们可以使用隐式或显式事务。再次 ADO.NET 事务有一些性能提升,但此时这并不是真正的问题。但是我们有锁定问题。在下面的示例代码中,虽然隔离级别设置为 ReadCommitted,但无法从其他客户端对表 testTable 进行 Select SQL 语句,直到主事务(在 Main 方法中)将被提交,因为整个表都有锁。我们还尝试在所有方法中仅使用一个连接,但行为相同。我们的 DBMS 是 SQL Server 2008。有什么我们不明白的地方吗?
问候安东卡尔奇克
请参阅此示例代码:
class Program
{
public class DAL
{
private const string _connectionString = @"Data Source=localhost\fsdf;Initial Catalog=fasdfsa;Integrated Security=SSPI;";
private const string inserttStr = @"INSERT INTO dbo.testTable (test) VALUES(@test);";
/// <summary>
/// Execute command on DBMS.
/// </summary>
/// <param name="command">Command to execute.</param>
private void ExecuteNonQuery(IDbCommand command)
{
if (command == null)
throw new ArgumentNullException("Parameter 'command' can't be null!");
using (IDbConnection connection = new SqlConnection(_connectionString))
{
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
}
}
public void FirstMethod()
{
IDbCommand command = new SqlCommand(inserttStr);
command.Parameters.Add(new SqlParameter("@test", "Hello1"));
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required))
{
ExecuteNonQuery(command);
sc.Complete();
}
}
public void SecondMethod()
{
IDbCommand command = new SqlCommand(inserttStr);
command.Parameters.Add(new SqlParameter("@test", "Hello2"));
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required))
{
ExecuteNonQuery(command);
sc.Complete();
}
}
}
static void Main(string[] args)
{
DAL dal = new DAL();
TransactionOptions tso = new TransactionOptions();
tso.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required,tso))
{
dal.FirstMethod();
dal.SecondMethod();
sc.Complete();
}
}
}