リンクサーバーで理解できない状況にあります。
したがって、2008R2サーバーから2014サーバーへのリンクサーバーがあります。以下のサンプルクエリは2008R2サーバーから実行されており、正常に動作します。
_SET XACT_ABORT ON;
Declare @BatchSize int = 10
DELETE from LINKEDSRV.DB.DBO.Table
INSERT INTO LINKEDSRV.DB.DBO.Table (ECN)
SELECT TOP (10) C1 from LINKEDSRV.DB.DBO.Table22 --order by C1
SELECT * FROM LINKEDSRV.DB.DBO.Table
_
しかし、同じことを_order by C1
_で実行すると、結果が返されません。
2番目のケース-TOP(10)
をTOP(@BatchSize)
に置き換え、_order by
_を使用しない場合も、結果が得られません。例えば
_SELECT TOP (@BatchSize) C1 from LINKEDSRV.DB.DBO.Table22
_
私が_SET XACT_ABORT OFF
_であれば、すべてのシナリオが機能します。リンクサーバーに関しては、XACT_ABORTには何らかの制限がありますか?
編集-さらにテストを行い、行数にも関係する必要があるようです。
可能なレポ
On ServerA
_use testdb
go
create table t1( c1 int, c2 datetime)
create table t2( c1 int, c2 datetime)
insert into t2 select 1, GETDATE()
insert into t2 select * from t2 -- insert close to 5000 rows, I found the issue around over around 35000 rows
_
On ServerB
ServerAへのリンクサーバーを作成する
_SET XACT_ABORT ON;
Declare @BatchSize int = 10
delete from ServerA.testdb.dbo.t1
insert into ServerA.testdb.dbo.t1 (c1)
select top (@BatchSize) c1 from ServerA.testdb.dbo.t2 --order by c2
select * from ServerA.testdb.dbo.t1
_
出力なし。しかし、テーブルt2の行数を約2000に減らすと、正常に機能します。
私が
SET XACT_ABORT OFF
であれば、すべてのシナリオが機能します。リンクサーバーに関しては、XACT_ABORT
にはなんらかの制限がありますか?
XACT_ABORT
の設定は、 サーバー間リモートストアドプロシージャのエラー処理 で説明されているように、リモートSQL Serverに伝達されます。
分散クエリと分散トランザクション に記載されているように、この設定は更新が可能かどうか、およびそれらの処理方法にも影響します。 SQL Serverはネストされたトランザクションをサポートするため、INSERT
はXACT_ABORT OFF
で許可されます。
それにもかかわらず、SQL Serverがスキーマロックを解放しようとするとエラーが発生することが挿入中に2014サーバーのアクティビティを追跡すると明らかになるため、実装のバグがあるように見えます。
このエラーは、リモートサーバー上のステートメント(スキーマロックの解放を試行)を中止しますが、XACT_ABORT
がOFF
の場合、リモートサーバーは処理を続行します次のステートメント。スキーマロックの解放エラーにもかかわらず、挿入は完了します。
XACT_ABORT
がON
の場合、リモートバッチ全体が中止されるため、挿入はロールバックされます。
ローカルで問題を再現できましたが、ORDER BY
句は重要ではありませんでした。
INSERT
を明示的なトランザクションでラップするなど、いくつかの方法で問題を回避できます(DTCが利用できると仮定)。
実装はカーソルモデルに基づいているため、リモート変更では4部構成の名前構文を使用しないことをお勧めします。通常、バルクメソッドを使用するか、リモートサーバーでデータをプルすることでプッシュするのではなく、パフォーマンスを向上させます。ローカルサーバー)。
関連するQ&Aを参照してください どちらが効率的ですか:リンクサーバーから選択するか、リンクサーバーに挿入しますか?
私の経験では、リンクサーバーを介してマルチパートコマンドを実行すると、通常、特にテーブルが大きい場合に問題が発生します。これを試して :
SET XACT_ABORT ON;
Declare @BatchSize int = 10
delete from ServerA.testdb.bbo.t1
select top (@BatchSize) c1 INTO #t2temp from ServerA.testdb.dbo.t2
insert into ServerA.testdb.dbo.t1 (c1)
SELECT * FROM #t2temp
select * from ServerA.testdb.dbo.t1