参照されたリンクサーバーを使用してストアドプロシージャと戦っています。リンクされたサーバーは、ポート転送を介してインターネット経由でアクセスできるため、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 に大きな問題があります
- 一部のユーザーが手動でプロシージャを呼び出すと、C# コードから例外が発生することがあります。
OLE DB プロバイダー 'SQLOLEDB' が分散トランザクションを開始できなかったため、操作を実行できませんでした。
- ストアド プロシージャ内に開始分散トランザクションを配置すると、次のようになりました。
警告: 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
}