2011-01-03 5 views
2

で実行されている更新クエリ:2私のようなステートメントを実行し、私は状況持っている(私は、しかし、状況を変更するオプションではありません)場合は、正確に同じ時間

Update Table 1 Set Field 5 = 'Blah' Where Field5 IS NULL 

そして、その文の実行まったく同じ時刻に複数回、同じ行が複数のスレッドによって更新されるのを避けるにはどうすればよいですか?

+0

うわあ、StackOverflowのに私の最初のポストと私はすでにそれを台無しに:それは、フィールド5には、私が持っているもの NULL IS 5 =「何とか」の私はをループする必要がある処理状況である アップデート表1セットのフィールドです一度に1つのレコードを取得し、処理し、次のレコードに移動します。しかし、問題は私がこれに取り組んでいる複数のスレッドを持っていると私は同じレコードが同時に複数のクエリで "つかんだ"と信じるように状況を見てきました。 – milkboneUnderwear

+0

あなたは状況を変えることができないので、私は全体のセットベースの操作をスキップし、なぜ現在の状況は悪い考えであるのでしょうか。何のRDBMSを使用していますか? –

+0

SQL 2000、SQL 2005、およびSQL 2008 – milkboneUnderwear

答えて

3

これは、ここに「作成されたサンプル」があるためですが、そのステートメントはすでに特定のレコードに対して1回だけ実行されます。

はフィールド5がnullであることを仮定します

Update Table 1 Set Field 5 = 'Blah' Where Field5 IS NULL 

今はフィールド5 = '何とか' この文をもう一度実行

...

Update Table 1 Set Field 5 = 'Blah' Where Field5 IS NULL 

は何もしません。レコードは、WHERE句には含まれなくなるため、最初の更新時のままになります。

+0

汚いデータの読み込みを許可するヒントを提供していない限り、同じ行が2回以上更新されることはありません。 –

+0

私は1000レコードほどのデータセットについて話しています。そして、レコードが更新されたらIDを返すことを話しています。私は、クエリが同時に実行され、レコードを取得し、更新し、IDを返します。同じIDが複数のスレッドにわたって返されることがあります。 – milkboneUnderwear

+0

そして、私は2回目のクエリの実行について話しているわけではありません。同じ時間にそれを実行することについて話しています。私はある種の競合状態があると確信しています.SQLがクエリを3回同時に実行する要求を出しても、SQLはそれらを並行して実行し、並行して実行しません。しかし、その場合でも、レコードを更新してそのレコードのIDを返すと、(ほぼ)同時に発生したクエリ呼び出しに対して同じIDが返されないように、各要求を分離する方法が必要です。 – milkboneUnderwear

0

また、(ダミー)ロックファイルでflockを使用して更新前のファイルを排他ロックし、その後ロックを解除しながら、スクリプトから更新を実行することもできます。

1

rowversionフィールド(旧バージョンのmssqlではtimestamp)を使用します。スレッドが現在のrowversionをチェックする必要があり、updateにはwhere句に余分な条件を付けて、古いrowversionを更新する必要があります。 rowversionフィールドは、行のいずれかのフィールドが変更されるたびに自動的に変更されるため、変更が一度しか行われません。

注:これは恐ろしいハックです。スレッドを修正して作業をより分かりやすくする方が良いでしょう。

+0

Donnie - 私は実際には、 "最高の"解決策は、スレッドを手作業で行う必要があることに同意しますが、彼はコードを制御しないと言います... DBのみ。コミュニケーションの問題のようなものは、問題の根源です。 :-) – Flipster

関連する問題