0

参照されたリンクサーバーを使用してストアドプロシージャと戦っています。リンクされたサーバーは、ポート転送を介してインターネット経由でアクセスできるため、VPN や LAN はありません。

サーバーは両側にありますMS SQL SERVER 2008 EE v. 10.0.5512

構成リンクサーバー、DTC:

まだ画像を挿入できません:(

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

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

ストアドプロシージャは次のようになります

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# コードは、データを同期するために無限に呼び出されます。同じスレッドで、ファイルからデータを取得し(存在する場合)、それらをローカルDBに保存する別のメソッドも呼び出されます。

SynchronizeArticles メソッドはより頻繁に呼び出され、すべてが機能していますが、ファイルからデータを取得するメソッドが呼び出されると、SynchronizeArticles は常にこの例外をスローします

System.Data.SqlClient.SqlException (0x80131904): サーバー 'LocalServer\SQLEXPRESS2008' の MSDTC は使用できません。

メソッドはトランザクションを使用しており、次のようになります

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 DTC に大きな問題があります

  1. 一部のユーザーが手動でプロシージャを呼び出すと、C# コードから例外が発生することがあります。

OLE DB プロバイダー 'SQLOLEDB' が分散トランザクションを開始できなかったため、操作を実行できませんでした。

  1. ストアド プロシージャ内に開始分散トランザクションを配置すると、次のようになりました。

警告: 2013 年 4 月 10 日午前 9 時 7 分に致命的なエラー 8510 が発生しました。エラーと時間を記録し、システム管理者に連絡してください。

唯一役立つのは、Windows サービスまたは UI アプリケーションの再起動です。MS SQL 管理スタジオからの手順は、問題なく常に機能します。

今、私は絶望的だと言わざるを得ません。何が欠けているのでしょうか?

編集:

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
      }
4

0 に答える 0