我刚刚尝试了在 SQL Server 2012 (EXPRESS) 中升级到分布式事务的行为。而且我观察到与 SQL Server 2008 相同的行为。
我已经在非常简单的带有SqlConnection
对象的代码上对其进行了测试。在一个事务范围内总是有两个数据库访问 (INSERT)。
非嵌套连接 - 未升级
如果您想避免升级为 DTC,这是唯一的选择。在事务期间仅访问一个持久资源(数据库)并在打开另一个连接之前关闭一个连接。(最终,您可以通过重用相同的连接来避免 DT,但是当您使用连接池时没有必要这样做,并且可能会使您的代码可读性降低。)
static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";
static void Main(string[] args)
{
using (var scope = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var command = conn.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "INSERT INTO TestTable(Value) VALUES (@1)";
command.Parameters.Add(new SqlParameter("1", "123456"));
command.ExecuteNonQuery();
}
}
using (var conn2 = new SqlConnection(connectionString))
{
conn2.Open();
using (var command2 = conn2.CreateCommand())
{
command2.CommandType = CommandType.Text;
command2.CommandText = "INSERT INTO TestTable(Value) VALUES (@1)";
command2.Parameters.Add(new SqlParameter("1", "123456"));
command2.ExecuteNonQuery();
}
}
scope.Complete();
}
}
嵌套连接 - 升级
static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";
static void Main(string[] args)
{
using (var scope = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
// EXECUTE INSERT
using (var conn2 = new SqlConnection(connectionString))
{
conn2.Open();
// EXECUTE INSERT
}
}
scope.Complete();
}
}
访问不同数据库的非嵌套连接 - 升级
如果您在事务期间访问两个或更多持久资源,它将始终被提升为 DTC。
static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";
static string connectionString2 = "data source=.\\;Integrated Security=SSPI;Database=TestDB2";
static void Main(string[] args)
{
using (var scope = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
// EXECUTE INSERT
}
using (var conn2 = new SqlConnection(connectionString2))
{
conn2.Open();
// EXECUTE INSERT
}
scope.Complete();
}
}
注意
您将执行哪种 CRUD 操作并不重要,它始终取决于打开和关闭连接的方式。