How to use transactions in SMO.Server ConnectionContext

心不动则不痛 提交于 2020-01-11 10:30:51

问题


Following examples 1, 2 I wrote the following:

using System;
using System.Data.SqlClient;
using System.IO;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

namespace ScriptRunner
{
    class Program
    {
        static void Main(string[] args)
        {
            var script = File.ReadAllText("Test.sql");
            const string sqlConnectionString = @"Data Source=my\ds;
                    Initial Catalog=myic;
                    Connection Timeout=0;
                    Integrated Security=true";
            SqlConnection connection = null;
            Server server = null;
            try
            {
                connection = new SqlConnection(sqlConnectionString);
                server = new Server(new ServerConnection(connection));
                connection.Open();
                server.ConnectionContext.BeginTransaction();
                server.ConnectionContext.ExecuteNonQuery(script);
                server.ConnectionContext.CommitTransaction();
            }
            catch { server.ConnectionContext.RollBackTransaction(); }
            finally { connection?.Dispose(); }
        }
    }
}

Everything works, except the transactions. The command just runs, if there is the error, everything before is already in database. How to make transactions work here?

[EDIT] When I change the code to open the transaction at the SqlConnection level like this (here it's suggested, that there should be no difference):

    SqlTransaction transaction = null;
    try
    {
        connection = new SqlConnection(sqlConnectionString);
        server = new Server(new ServerConnection(connection));
        connection.Open();
        transaction = connection.BeginTransaction();
        server.ConnectionContext.ExecuteNonQuery(script);
        transaction.Commit();
    }

It throws InvalidOPexception : "ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized."

Yet I do not see a place where I can access the command object.


回答1:


I've faced with same problem "ExecuteNonQuery requires the command to have a transaction...".
It seems that if perform begin/commit transaction for ServerConnection, not for SqlConnection then everything works.

...
SqlConnection connection = new SqlConnection(sqlConnectionString);
ServerConnection srvCon = new ServerConnection(connection);

try
{
     server = new Server(srvCon);

     srvCon.BeginTransaction();
     server.ConnectionContext.ExecuteNonQuery(script);
     srvCon.CommitTransaction();
}
catch
{
     srvCon.RollBackTransaction();
}
...


来源:https://stackoverflow.com/questions/47204709/how-to-use-transactions-in-smo-server-connectioncontext

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!