0

我玩了几天与链接服务器使用的存储过程有关的烦人问题。在我共享数据库的服务器上。服务器正在运行 MS SQL Server 2008 EE sp3。作为新用户,我不能放图像,所以我会尝试不

所以假设我有看起来的存储过程

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

配置链接服务器的位置

编辑:

enable promotion of distributed transaction = false
RPC = false
RPC out = false

当我从 MS SQL 管理工作室运行查询时,它总是成功运行。当我从 c# 应用程序代码运行查询时

StringBuilder sb;
    public bool ActualizeArticlesFromServer(Int64 siteId, out string messages)
    {
      SqlCommand sqlCmd = new SqlCommand("spSynchronizeArticles");
      try
      {
        sb = new StringBuilder();
        sqlCmd.CommandType = CommandType.StoredProcedure;
        sqlCmd.Parameters.AddWithValue("@pDebug", "false");
        sqlCmd.Parameters.AddWithValue("@siteId", siteId);

        // Return value as parameter
        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;
              //TODO: find out how to print from stored procedure
              //((SqlConnection)Context.LocalData.Connection).InfoMessage += new SqlInfoMessageEventHandler(Connection_InfoMessage);
               sqlCmd.ExecuteScalar();
            }
            catch (Exception ex)
            {
              Log.LogMethodException(ex);
              return false;
            }
          }
          finally
          {
            try
            {
              conn.Close();
            }
            catch (Exception ex) 
            {
              Log.LogMethodException(ex);
            }
          }
        }

        return Convert.ToInt64(returnValue.Value) == 0;
      }
      finally
      {
        messages = sb.ToString();
      }
    }

我在应用程序中有用户列表,但它是在内部解决的。没有 Windows 用户。

当我为实际用户运行此代码时,一切正常,我可以运行查询更多时间。然后我更改用户并尝试从上面的代码执行过程我得到了异常

System.Data.SqlClient.SqlException (0x80131904): The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "someServer" was unable to begin a distributed transaction.

当我重新启动整个应用程序时,查询再次正常工作。我不知道它是否与连接池或什么有关?

我认为分布式事务以某种方式挂起(但在 SQL 中没有使用事务)。

在 DTC 统计信息中,即使触发了异常,我也可以看到活动事务。

我已经在客户端和服务器上设置了 DTC 组件确实允许一切(它是捷克语,但我希望它足够清楚)

Network DTC Access checked
Allow inbound true
Allow outbound true
No authentication Required

服务器 SQL 服务器安装在带有 Microsoft Windows Server 2008 的虚拟计算机上。当 DTC 设置在 Windows 服务器和虚拟 Windows 服务器上时。防火墙用于在服务器和虚拟机上进行测试。

编辑2:

好的。所以我做了一些研究,看起来@JanVanHerck 是对的。这对我来说仍然很困惑,但我会尝试写下我所做的。

  1. 我关闭 MS DTC
  2. 第一次运行我的应用程序代码来执行存储过程并且工作正常
  3. 然后我注销了,我的注销方法做了一些我在下面解释的事情。
  4. 我使用相同的用户名登录(确实没关系)并运行我的应用程序代码来执行存储过程,并且 MS DTC 未在计算机上运行的异常出现。

注意:存储过程中没有事务(也没有分布式事务)。

所以我检查了注销方法,我发现我正在更新事务中的一个本地表 - 我在代码中注释了事务并且一切正常。

我会尝试将其放入生产系统中并会看到,但我们在这里有一些改进。谢谢@JanVanHerck。其实我之前没有检查我的代码,因为我不知道它可能会影响执行程序。

但有趣的是,MS DTC 在使用事务后会出现(即使仅在本地数据库中)。

4

0 回答 0