首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SQL Server2012中使用TransactionScope

在SQL Server2012中使用TransactionScope
EN

Stack Overflow用户
提问于 2012-10-02 17:58:16
回答 2查看 2.9K关注 0票数 2

我读过Pieter De Rycke写的一篇很棒的文章:

http://pieterderycke.wordpress.com/2012/01/22/transactionscope-transaction-escalation-behavior/

我曾尝试在internet上搜索有关SQL Server 2012中事务升级行为的文档,但没有成功。

是否有人知道SQL Server2012的行为是否与SQL2008不同?我目前对TransactionScope和提升到DTC有问题(我不想要)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-05 21:18:34

我刚刚尝试过如何在SQL Server 2012 (EXPRESS)中升级到分布式事务。我观察到了与SQL Server 2008相同的行为。

我已经用SqlConnection对象在非常简单的代码上对它进行了测试。在一个事务作用域中总是有两个数据库访问(插入)。

未嵌套连接-未升级

如果您不想升职到DTC,这是唯一的选择。在事务期间仅访问一个持久资源(数据库),并在打开一个连接之前关闭另一个连接。(最终,您可以通过重用相同的连接来避免DT,但当您使用连接池时,这并不是必需的,并且可能会降低代码的可读性。)

代码语言:javascript
复制
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();
    }
}

嵌套连接-升级

代码语言:javascript
复制
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。

代码语言:javascript
复制
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操作并不重要,它始终取决于打开和关闭连接的方式。

票数 2
EN

Stack Overflow用户

发布于 2013-10-11 16:18:38

在@mipe34的第三种情况下(同一服务器上的不同数据库),实际上有一种方法可以通过使用DbConnection.ChangeDatabase()来防止DTC升级。

代码语言:javascript
复制
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()一个连接,而另一个仍然是开放的。在这种情况下,您将得到升级。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12688197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档