問題は、シノニムがトランザクションの範囲外(および現在の接続も)にアクセスできることであると思います。SSMS の異なるタブで 2 つのコード セットを実行してみてください。
別のタブの 2 番目のクエリは、最初のクエリが完了するまで 10 秒間待機します。
-- first tab:
BEGIN TRAN
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
waitfor delay '00:00:10'
SELECT * FROM S
DROP SYNONYM S
COMMIT TRAN
-- second tab:
BEGIN TRAN
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
SELECT * FROM S
DROP SYNONYM S
COMMIT TRAN
これらのクエリを実行すると、2 番目のクエリはCREATE
ステートメントで失敗しますが、select から行が返され、トランザクションがコミットされるのを待ちません。
-- first tab:
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
waitfor delay '00:00:10'
SELECT * FROM S
DROP SYNONYM S
--second tab:
CREATE SYNONYM S FOR [ServerIP].[MyDatabase].[dbo].[MyTable]
SELECT * FROM S
DROP SYNONYM S
複数のセッションが同じシノニムを削除して作成しようとするのを防ぐために考えられる解決策:
- 同義語を使用しないでください:)
- 最初にシノニムが存在するかどうかを確認します (ただし、その特定の名前のシノニムが正しいテーブルを指しているという保証はありません)。
if not exists(select * from sys.synonyms where name = 's') create synonym s for [MyDatabase].[dbo].[MyTable]
- プロシージャのすべてのインスタンスで使用される永続的なシノニムを作成します