SQL Server 2014 AGグループ(AG1)にデータベースがあります。-2つのノード。
両方のノードで、リンクサーバーがセットアップされます。 AGグループ(AG1)データベースのテーブルからデータを選択し、リンクサーバー(別のAGグループ(AG2)のデータベース)に挿入しています。トランザクションの唯一のステートメントは、挿入ステートメントです。分散トランザクションではありません。
次のエラーが発生するのはなぜですか?
リンクサーバー "LinkedserverListener"のOLE DBプロバイダー "SQLNCLI11"は、メッセージ "トランザクションマネージャーがリモート/ネットワークトランザクションのサポートを無効にしました。"を返しました。
メッセージ7391、レベル16、状態2、行2
リンクサーバー "LinkedServerListener"のOLE DBプロバイダー "SQLNCLI11"が分散トランザクションを開始できなかったため、操作を実行できませんでした。
サンプルコードは以下です。
Drop table #Myatran
Select 'ABC' name into #Myatran
DECLARE @pndstop_ps NVARCHAR(4000)
SET @pndstop_ps =
N'
INSERT INTO '+ 'linkedserver'+'.DB.dbo.MyaTEST(Name) SELECT name FROM #Myatran
'
SET XACT_ABORT ON
BEGIN TRANSACTION
EXEC sp_executeSQl @pndstop_ps
SET XACT_ABORT OFF
SQL Server 2014可用性グループ サポートしていません 分散トランザクション。
SQL Server 2016は 分散トランザクションのサポートに制限がありますが、SQL Server 2017が最もサポートされています 。
SQL Server Integration Services、bcp in/out、またはExtract-Transform-LoadまたはETL操作用のその他のツールの使用を検討してください。
ちなみに、あなたはこれに気づいていないかもしれませんが、INSERT INTO ...
をリンクサーバー上のテーブルに挿入すると、ローカルSQL Serverが、ターゲットテーブルに挿入された各行に対して一連のカーソル呼び出しを実行します。
これを証明するために、リンクサーバーを作成し、次のコードを実行して簡単なテストベッドをセットアップしました。
まず、リンクサーバーのtempdbにテーブルを作成します。
DECLARE @cmd nvarchar(max);
SET @cmd = 'IF OBJECT_ID(''dbo.InsertTest'', N''U'') IS NOT NULL
DROP TABLE dbo.InsertTest;
CREATE TABLE dbo.InsertTest
(
id int NOT NULL PRIMARY KEY CLUSTERED
);';
EXEC [LinkedServer].tempdb.sys.sp_executesql @cmd;
ここでは、いくつかの行を保持するためにtempdbにローカルテーブルを作成しています。
IF OBJECT_ID('dbo.InsertTest', N'U') IS NOT NULL
DROP TABLE dbo.InsertTest;CREATE TABLE dbo.InsertTest
(
id int NOT NULL PRIMARY KEY CLUSTERED
);
INSERT INTO dbo.InsertTest (id)
SELECT ROW_NUMBER() OVER (ORDER BY c.object_id, c.column_id)
FROM sys.columns c;
ソーステーブルに行があるかどうかを確認する簡単なチェック:
SELECT CountOfRows = COUNT(1)
FROM dbo.InsertTest;
╔═════════════╗ ║CountOfRows║ ╠═════════════╣ ║990 ║ ╚═════════════╝
ここでは、ローカルのソーステーブルからリモートのリンクサーバーテーブルに行を挿入します。ターゲットサーバーで実行されるトレースを設定して、それに対して発行されたT-SQLステートメントを確認できるようにしました。
INSERT INTO [LinkedServer].tempdb.dbo.InsertTest (ID)
SELECT it.ID
FROM dbo.InsertTest it;
出力:
╔═════════════════════════════════════════════════ ══════════════════════════════════════════════════ ══════════╗ ║SET XACT_ABORT OFF║ ╠═══════════════════════ ══════════════════════════════════════════════════ p ║@ p1 int║[を宣言します。 ____。]║set @ p1 = NULL║ ║declare @ p2 bigint║ ║set @ p2 = NULL║ ║exec [sys] .sp_getschemalock @ p1 output、@ p2 output、N '"tempdb"。 "dbo"。 "InsertTest"'║ ║select @ p1、@ p2 p ║declare @ p1 int║ ║set @ p1 = NULL║ ║declare @ p3 int║ ║set @ p3 = 229378║ ║declare @ p4 int║ ║set @ p4 = 294916║ ║declare @ p5 int║ ║set @ p5 = NULL ║ ║exec sp_cursoropen @ p1 output、N'select * from "tempdb"。 "dbo"。 "InsertTest" '、@ p3 output、@ p4 output、@ p5 output║ ║select @ p1、@ p3、@ p4、@ p5║ ║exec sp_cursor 180150027,4,0、N '[tempdb]。[dbo]。[InsertTest]'、@ id = 1║ ║exec sp_cursor 180150027,4,0、N '[tempdb]。[dbo]。[InsertTest]'、@ id = 2║ ║exec sp_cursor 180150027,4,0、N '[tempdb]。 [dbo]。[InsertTest] '、@ id = 3║ ║exec sp_cursor 180150027,4,0、N' [tempdb]。[dbo]。[InsertTest] '、@ id = 4║ ║exec sp_cursor 180150027,4,0、N '[tempdb]。[dbo]。[InsertTest]'、@ id = 5 。 。 ║exec sp_cursor 180150027,4,0、N '[tempdb]。[dbo]。[InsertTest]'、@ id = 987║ ║exec s p_cursor 180150027,4,0、N '[tempdb]。[dbo]。[InsertTest]'、@ id = 988║ ║exec sp_cursor 180150027,4,0、N '[tempdb]。[dbo] 。[InsertTest] '、@ id = 989║ ║exec sp_cursor 180150027,4,0、N' [tempdb]。[dbo]。[InsertTest] '、@ id = 990║ ║exec [sys] .sp_releaseschemalock 1║ ║exec sp_cursorclose 180150027║ ║exec sp_reset_connection║ ╚════════════════ ══════════════════════════════════════════════════ ═══════════════════════════════════════════╝
ただし、次のようにターゲットサーバーから挿入を実行すると、
INSERT INTO dbo.InsertTest (ID)
SELECT it.ID
FROM [LinkedServer].tempdb.dbo.InsertTest it;
あなたはこれをトレースで見る:
╔════════════════════════╦════════════════════════ ════════════════════════╗ ║TextData║。 ╠══════════ ══════════════╬═══════════════════════════════════ ═════════════╣ ║SET STATISTICS XML ON║║ ║║INSERT INTO dbo.InsertTest(ID)║ ║║SELECT it.ID║ ║║FROM [CP708-D377\MV] .tempdb.dbo.InsertTest it; ║ ║SET STATISTICS XML OFF║║ ╚════════════════════════╩══════ ══════════════════════════════════════════╝
明らかに、ソースサーバーではなく、ターゲットサーバーで挿入を実行することは効果的です。