リンクサーバーの使用に関するストアドプロシージャに関する厄介な問題で数日間遊んでいます。サーバー上でDBを共有しています。サーバーは 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 Management Studio からクエリを実行すると、常に正常に実行されます。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
DTC が Windows サーバーと仮想 Windows サーバーに設定されている場合、サーバー SQL サーバーは Microsoft Windows Server 2008 を使用して仮想コンピューターにインストールされます。ファイアウォールは、サーバー上と仮想上でのテストに使用されました。
EDIT2:
わかった。だから私はいくつかの調査を行い、@JanVanHerckが正しかったように見えます. まだ混乱していますが、私がやったことを書いてみます。
- MS DTC をオフにします
- 初めてアプリケーション コードを実行してストアド プロシージャを実行し、正常に動作したとき
- 次に、ログアウトすると、ログアウト メソッドが何かを実行しました。これについては、以下で説明します。
- 同じユーザー名でログインし (実際には関係ありません)、アプリケーション コードを実行してストアド プロシージャを実行すると、MS DTC がコンピューターで実行されていないという例外が発生します。
注: ストアド プロシージャ内にはトランザクションはありません (分散トランザクションもありません)。
そのため、ログアウト方法を確認すると、トランザクション内の 1 つのローカル テーブルを更新していることがわかります。コードでトランザクションにコメントすると、すべてが機能しています。
私はそれを生産システムに入れようとしますが、ここでいくつかの改善があります. ありがとう@JanVanHerck。実際、プロシージャの実行に影響を与える可能性があることを知らなかったので、以前はコードをチェックしていませんでした。
しかし興味深いのは、トランザクションが使用された後に MS DTC が表示されることです (ローカル DB のみでも)。