userB が OrderA を変更している間に userA が OrderA を削除した場合、userB が OrderA を保存すると、データベースに更新する注文はありません。私の問題はエラーがないことです!SqlDataAdapter.Update は成功し、これが true でない場合、レコードが変更されたことを示す "1" を返します。これがどのように機能するか知っている人はいますか、ありがとう。
4 に答える
ステートレスで動作しない場合 (Web サービスの動作など)、ペシミスティック ロックを試すことができます。詳細はこちら (ただし VB の例): https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-1049842.html
少なくとも、楽観的ロックを使用する必要があります。ここを参照してください:
基本的に、これは更新中にすべてのフィールドの値を確認することを意味します。たとえば、最初にレコード 1 を読んだとき、バーが 0 だったとします。
UPDATE FOO SET BAR=1 WHERE ID=1 AND BAR=0
アイデアは、レコードが変更された場合、更新が失敗するということです。これで問題が解決します。
また、オプティミスティック コンカレンシーが最善の方法だと思います。
更新の基準としてどのデータベース フィールドの使用が失敗したかだけを決定する必要があります。状況によって異なりますが、これを実装するための普遍的な方法が 1 つあります。私は個人的に MS SQL Server を使用しているため、データベースのすべてのテーブル (テーブルごとに 1 つのフィールド) にnull 値を許容しないrowversion
フィールド (エイリアス) を挿入することを好みます。timestamp
したがって、テーブルのすべての行には「rowversion
」があり、誰かが行のフィールドを更新すると自動的に更新されます。したがって、更新の基準が失敗するため、このフィールドを使用する必要があります。詳細については、古い回答の SQL トランザクションの同時実行処理も参照してください。
更新:SqlDataAdapter
データベースにアクセスするために使用するため、次のリンクも興味深いものになる可能性があります。
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-1050108.html
そして次のもので検索するだけですDataRowVersion
:
http://msdn.microsoft.com/en-us/library/ww3k31w0(VS.71).aspx、 http://msdn.microsoft.com/en-us/library/bbw6zyha(VS.80).aspx、 http://msdn.microsoft.com/en-us/library/ms971491.aspx、 http://msdn.microsoft.com/en-us/magazine/cc163908.aspx
私はあなたと同じような状況に遭遇しました。これには、 、それに接続された 、および オブジェクトが含まSqlDataAdapter
れSqlCommandBuilder
ていましたDataTable
。一貫して行った変更は保存に失敗しましたが、エラーは発生しませんでした。DataTable
オブジェクトの列の 1 つが間違った名前であることが判明しました。修正したら、完全に機能するようになりました。これでエラーが発生しなかった理由はまだわかりません。