SQL Server(2012)非ブロッキングDDL?
-
22-10-2019 - |
質問
私はSQL Serverの経験があまりないので、何かが足りないのかもしれません
私の状況は次のとおりです。
- セッション1では、オートコンミットをオフにして作成テーブル(またはその他の作成ステートメント)を実行しますが、作成はコミットされていません。
- セッション2はaを実行します
sp_table
ステートメントですが、セッション1がDDLをコミットしていない限りハングします
これが起こるシナリオは、データベースに取り組んでいる開発者です。それらのいくつかはテーブルを閲覧しており、その一部はDDLをやっています。 1人のユーザーがDDLのコミットを忘れた場合、テーブルをリストしたい他のすべてのセッションがブロックされます。に注意してください sp_tables
(JDBCドライバーAPIを介して)SQLクライアントによって発行されるため、変更できるものではありません。
私が扱っているデータベースにはSnapshot_isolationが有効になり、分離レベルがコミットされた読み取りに設定されています(SET ALLOW_SNAPSHOT_ISOLATION ON
と SET READ_COMMITTED_SNAPSHOT ON
)
私の仮定は、これらの設定が、SQLサーバーを、同時セッション(例:PostgreSQLやOracleがどのライターによってブロックされないようなPostgreSQLやOracleのように)をより良くするようにする必要があるということでしたが、明らかにそうではありません。
それでは、DDLに関して、SQL Serverを同時の読み取り/書き込み状況に対してより友好的にする方法はありますか? (自動コミットモードでのみDDLを送信することとは別に)。
解決
いいえ、SQL Serverを構成してやりたいことを実行する方法はありません。
スナップショットの分離の下で呼び出し sp_tables
システムベーステーブルの1つで共有キーロックを待ってブロックされます(sysschobjs
)しているとき SELECT
から sys.all_objects
行バージョンベースの分離レベルを使用します BOLのトピックは言っています:
SQL Serverは、システムメタデータの複数のバージョンを保持しません。データ定義言語(DDL)テーブルおよびその他のデータベースオブジェクト(インデックス、ビュー、データ型、ストアドプロシージャ、および共通言語ランタイム関数)のステートメントはメタデータを変更します。
下でも TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
通話 sp_tables
ただし、すぐに前向きにブロックすることになります SELECT ... FROM sys.all_objects
同じクエリ参照をブロックしなくなりました HAS_PERMS_BY_NAME
の関数 WHERE
句。これはシステムトランザクションを開始するようです(CMetadataAccessor::CMetadataAcce
)より高い分離レベルで、最終的に共有キーロックを待っているのを待ってしまうことになります sysschobjs
また。
他のヒント
アイデア:15秒ごとにジョブをスケジュールして、アイドルしていないDDLを探し、セッションを終了して再び取り戻します。