我读过Pieter De Rycke写的一篇很棒的文章:
http://pieterderycke.wordpress.com/2012/01/22/transactionscope-transaction-escalation-behavior/
我曾尝试在internet上搜索有关SQL Server 2012中事务升级行为的文档,但没有成功。
是否有人知道SQL Server2012的行为是否与SQL2008不同?我目前对TransactionScope和提升到DTC有问题(我不想要)
发布于 2012-12-05 21:18:34
我刚刚尝试过如何在SQL Server 2012 (EXPRESS)中升级到分布式事务。我观察到了与SQL Server 2008相同的行为。
我已经用SqlConnection对象在非常简单的代码上对它进行了测试。在一个事务作用域中总是有两个数据库访问(插入)。
未嵌套连接-未升级
如果您不想升职到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操作并不重要,它始终取决于打开和关闭连接的方式。
发布于 2013-10-11 16:18:38
在@mipe34的第三种情况下(同一服务器上的不同数据库),实际上有一种方法可以通过使用DbConnection.ChangeDatabase()来防止DTC升级。
static string connectionString = "data source=.\\;Integrated Security=SSPI;Database=TestDB";
static string db2 = "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(connectionString))
{
conn2.Open();
conn2.ChangeDatabase(db2);
// EXECUTE INSERT
}
scope.Complete();
}
}只要确保你永远不会Open()一个连接,而另一个仍然是开放的。在这种情况下,您将得到升级。
https://stackoverflow.com/questions/12688197
复制相似问题