1

実験の詳細:

これを Microsoft SQL Server 管理スタジオで実行しています。私が実行する1つのクエリウィンドウで:

BEGIN TRANSACTION a; 
      ALTER table <table name> 
            ALTER column <column> varchar(1025) 

もう一方は次のように実行します。

SELECT 1 
       FROM sys.objects 
       WHERE name = ' <other_table name>'

またはこれ:

SELECT 1 
       FROM sys.objects 
       WHERE object_id = OBJECT_ID(N'[<other_table name>]')

何らかの理由で、トランザクションにコミットするまで name= を使用した選択が返されません。

DBに時々あるalter columnの長い操作をシミュレートするためにトランザクションを行っています。他の操作に害を与えたくありません。

4

1 に答える 1

0

これは、デフォルトのトランザクション分離レベル、つまり ReadCommited で作業しているためです。
Read Commited
Under Read Commited Trasanction Isolation Level でトランザクションを明示的に開始する Sql サーバーは、データの整合性を維持し、ユーザーによるダーティ リードを防止するために、リソースの排他ロックを取得します。トランザクションを開始していくつかの行を操作すると、トランザクションをコミットするかロールバックするまで、他のユーザーはそれらの行を表示できません。ただし、これは SQL Server のデフォルトの動作であり、たとえば Read Uncommited の下など、さまざまなトランザクション分離レベルで変更できます。他のユーザーによって変更/使用されている行を読み取ることができますが、「ダーティ リード」データが発生する可能性があります。まだデータベースにあると思われますが、他のユーザーが変更しました。」
私の提案
Dirty Reads が受け入れられるものである場合は、

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED;

それ以外の場合は、Sql Server のデフォルトの動作に固執し、ユーザーにダーティ/間違ったデータを与えるのではなく、少し待つようにしてください。お役に立てば幸いです。
編集

両方のクエリが同じ分離レベルで実行されているか、異なる分離レベルで実行されているかは関係ありません。重要なのは、クエリが実行されている分離レベルであり、明示的なトランザクションを使用する場合は、Read Uncommited トランザクション分離レベルが必要です。トランザクション中に他のユーザーがデータにアクセスできるようにする場合。推奨されておらず、悪い習慣ですが、tempdb を広範囲に利用し、最後にコミットされたデータのみを表示する Snapshot Isolation を個人的に使用します。

于 2013-11-15T08:36:05.017 に答える