2009-07-01 12 views
2

select/insertクエリを実行すると、SQL Serverは自動的に暗黙のトランザクションを作成し、それを1つのアトミック操作として扱いますか?SQL Serverは選択をラップしますか?クエリを暗黙的なトランザクションに挿入しますか?

それがまだない場合、テーブルに値を挿入し、次の問合せください:

INSERT INTO Table1 (FieldA) 
SELECT 'newvalue' 
WHERE NOT EXISTS (Select * FROM Table1 where FieldA='newvalue') 

の評価との間に別のユーザーがテーブルに挿入されている「NEWVALUE」のいずれかの可能性がありますWHERE句と、INSERT句がトランザクションで明示的にラップされていない場合は、それを実行しますか?

+0

は(あるいは、なぜしない):ここで説明しますか?あなたが探しているもののように思える、重複を避けるための良い方法のようです。 – JonnyBoats

+0

詳細には入りませんが、複雑な理由からDBに制約を直接追加することはできません(このため、このタイプのクエリでは私の作業がわかります)。 – JohnFx

+0

さて、私はあまりにも頭がよく見えません。私は少しの背景を与えるでしょう。 DBは、実行された実際のSQLを構築するAPIを通じて照会している第三者の製品によって管理され、所有されています。それはトランザクションのサポートを持っておらず、オブジェクトのデータベースを変更するとデータベースが保証を無効にする可能性があります。 =) – JohnFx

答えて

5

トランザクションとロックの間に混乱があります。エラーがあれば、トランザクションはデータを元の状態に戻します。そうでない場合は、データを新しい状態に移動します。操作が処理されると、データが断続的な状態になることは決してありません。一方、ロックは、複数のユーザーが同時にデータにアクセスすることを許可または禁止します。あなたの質問に答えるには、... insertはアトミックであり、細かいロックが明示的に要求されない限り、他のユーザーはselect..insertの実行中に挿入できません。

+0

それほど多くはありません。私はその違いを理解しています。私がトランザクションを述べた理由は、それがクリティカルセクション/ロックを指定するためのSQLサーバーの主要なメカニズムであるように思われるためです。 いずれにしても、あなたの答えに感謝します。 – JohnFx

2

Johnこの回答は現在の分離レベルによって異なります。 READ UNCOMMITTEDに設定されている場合は、問題を探すことができますが、分離レベルが高い場合は、選択と挿入の間にテーブル内の追加レコードを取得すべきではありません。 READ COMMITTED(デフォルト)、REPEATABLE READ、またはSERIALIZABLE分離レベルの場合は、カバーする必要があります。

+0

私は暗黙的なトランザクションを使用し、明示的なトランザクションを使用しないので、デフォルト(READ COMMITTED)がこの状況で使用されていると仮定しています。それは正しい? – JohnFx

+0

はい - 分離レベルはトランザクションとは別になっているため、ロックヒントを使用して変更するか、明示的に設定しない限り、同じレベルになります。 –

関連する問題