Sql server 2008 具有引用的linkedserver的存储过程

Sql server 2008 具有引用的linkedserver的存储过程,sql-server-2008,tsql,c#-4.0,stored-procedures,linked-server,Sql Server 2008,Tsql,C# 4.0,Stored Procedures,Linked Server,我正在使用引用的linkedserver处理存储过程。链接的服务器可以通过端口转发在internet上访问-因此没有VPN和LAN 服务器位于MS SQL SERVER 2008 EE v的两侧。10.0.5512 配置链接服务器,DTC: 尚未插入图像:( 存储过程看起来像 CREATE PROCEDURE [dbo].[spSynchronizeArticles] -- Add the parameters for the stored procedure here ( @

我正在使用引用的linkedserver处理存储过程。链接的服务器可以通过端口转发在internet上访问-因此没有VPN和LAN

服务器位于MS SQL SERVER 2008 EE v的两侧。10.0.5512

配置链接服务器,DTC:

尚未插入图像:(

存储过程看起来像

CREATE PROCEDURE [dbo].[spSynchronizeArticles] 
    -- Add the parameters for the stored procedure here
(
    @pDebug bit,
    @siteId bigint
)
AS
BEGIN

  SELECT *
  FROM [LinkedServer].[MyDatabase].dbo.Storages 
  WHERE Storage.siteId = @siteId

  RETURN 0

END
您在这里看不到任何事务。如果我是正确的,则每次调用链接服务器时,MS DTC都会创建事务

我是这样从c#调用这个过程的

  SqlCommand sqlCmd = new SqlCommand("spSynchronizeArticles");
  sqlCmd.CommandType = CommandType.StoredProcedure;
  sqlCmd.Parameters.AddWithValue("@pDebug", false);
  sqlCmd.Parameters.AddWithValue("@siteId", siteId);

  SqlParameter returnValue = new SqlParameter("returnVal", SqlDbType.Int);
  returnValue.Direction = ParameterDirection.ReturnValue;
  sqlCmd.Parameters.Add(returnValue);

  using (SqlConnection conn = new SqlConnection(Context.LocalData.ConnectionString))
  {
    try
    {
      try
      {
        conn.Open();
        sqlCmd.Connection = conn;
        sqlCmd.ExecuteScalar();

        return Convert.ToInt32(returnValue.Value);
      }
      catch (Exception ex)
      {
        //log exception to file
        return -1;
      }
    }
    finally
    {
      conn.Close();
    }
  }
}
此c#代码在无限期中被调用以同步数据。在同一线程中,还有另一个方法被调用,该方法从文件(如果存在)中获取数据并将其保存到本地数据库

SynchronizeArticles方法调用的频率更高,一切正常,但一旦调用了从文件获取数据的方法,SynchronizeArticles总是抛出此异常

System.Data.SqlClient.SqlException(0x80131904):服务器上的MSDTC “LocalServer\SQLEXPRESS2008”不可用

该方法正在使用事务,如下所示

public void FillDataFromViewWithTrans(DataTable dt, string wherePhrase)
    {
      dt.Rows.Clear();
      SqlCommand sql = new SqlCommand(String.Format(@"SELECT * 
FROM SomeView
{0}", String.IsNullOrEmpty(wherePhrase) ? String.Empty : "WHERE " + wherePhrase));


      using (SqlConnection conn = new SqlConnection(Context.LocalData.ConnectionString))
      {
        SqlTransaction trans = null;
        try
        {
          try
          {
            conn.Open();
            trans = conn.BeginTransaction(IsolationLevel.RepeatableRead);
            sql.Transaction = trans;
            sql.Connection = conn;

            SqlDataAdapter dA = new SqlDataAdapter(sql);

            dA.Fill(dt);

            trans.Commit();
          }
          catch (Exception ex)
          {
            trans.Rollback();
            //log exception to file
            return;
          }
        }
        finally
        {
          conn.Close();
        }
      }
    }
这只是示例:)

告诉我我错过了什么

此外,我有很大的麻烦与MS故障诊断码与各种错误

  • 从C#代码中,当一些用户手动调用过程时,有时会出现异常:
  • 无法执行该操作,因为OLE DB提供程序 “SQLOLEDB”无法开始分布式事务

  • 当我将begin distributed事务放入存储过程中时,我得到:
  • 警告:致命错误8510发生在2013年4月10日上午9:07。注意 错误和时间,并与系统管理员联系

    唯一有帮助的是重新启动windows服务或UI应用程序。从MS SQL management studio中,该过程始终运行,没有任何问题

    现在我必须说我绝望了,我错过了什么

    编辑:

    int i = 0;
          while (true)
          {
            i++;
            if ((i % 9) == 0)
            {
              //local select with transaction Works all the time
              CallLocalSelectWithTransaction(); 
            }
    
            // CallProcedure works 8 times, after first calling of CallLocalSelectWithTransaction
            // the callProcedure works no more.
    
            CallProcedure(); // procedure with linked server
          }
    

    关于错误“System.Data.SqlClient.SqlException(0x80131904):服务器“server_name”上的MSDTC不可用。”-您应该为远程访问启用DTC-检查此项感谢您的回答,但我已为远程访问启用DTC,一切正常。但当我用事务调用另一个c代码时,下一次调用存储过程会在服务器上抛出异常MSDTC。。。唯一可行的方法是根本不在代码中使用事务(我现在正在这样做),但这确实是一个糟糕的方法。我找到了一个可以测试DTC和的工具。防火墙应该关闭,我再次检查。有关模拟使用方法的代码,请参见我的编辑。如您所见,程序运行8次正常,因此MS DTC必须正在运行。
    int i = 0;
          while (true)
          {
            i++;
            if ((i % 9) == 0)
            {
              //local select with transaction Works all the time
              CallLocalSelectWithTransaction(); 
            }
    
            // CallProcedure works 8 times, after first calling of CallLocalSelectWithTransaction
            // the callProcedure works no more.
    
            CallProcedure(); // procedure with linked server
          }