質問

私はSQL Serverの経験があまりないので、何かが足りないのかもしれません

私の状況は次のとおりです。

  • セッション1では、オートコンミットをオフにして作成テーブル(またはその他の作成ステートメント)を実行しますが、作成はコミットされていません。
  • セッション2はaを実行します sp_table ステートメントですが、セッション1がDDLをコミットしていない限りハングします

これが起こるシナリオは、データベースに取り組んでいる開発者です。それらのいくつかはテーブルを閲覧しており、その一部はDDLをやっています。 1人のユーザーがDDLのコミットを忘れた場合、テーブルをリストしたい他のすべてのセッションがブロックされます。に注意してください sp_tables (JDBCドライバーAPIを介して)SQLクライアントによって発行されるため、変更できるものではありません。

私が扱っているデータベースにはSnapshot_isolationが有効になり、分離レベルがコミットされた読み取りに設定されています(SET ALLOW_SNAPSHOT_ISOLATION ONSET 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を探し、セッションを終了して再び取り戻します。

ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top