0

助けが必要です。まず、小さなサンプルでシナリオを説明しましょう。

列のあるStudentsテーブルがあるとします。

Id int(PK)  
Name varchar(200)  
Marks1 int  
Marks2 int  
Marks3 int  
TotalMarks int  
IsTotalCalculated bit  
InProcess bit

このテーブルには膨大な数のレコードがあります。

次に、各学生のTotalMarksを計算して、TotalMarks列を更新します。

C#コンソールアプリに来て、ストアドプロシージャを呼び出しています。

SP1 => InProcess=0およびIsTotalCalculated=0の上位2つのレコードを一度にフェッチし、そのInProcess = 1を設定して、処理を実行します。(SELECTとUPDATEがあります)

SP2 =>最後に、IsTotalCalculated=1およびInProcess=0を更新するこれらの2つの行を再度更新します(UPDATE)

懸念事項:私の懸念は、処理する2つの行を選択するとすぐに、他のコンソールアプリインスタンスがこれらの2つの行を処理対象として選択しないようにすることです。私は何をすべきか?
注:2つのSPのC#コードをTransactionBlockに配置しました。

ありがとう、

ジャスティン・サミュエル

4

3 に答える 3

1

InProcess = 1の場合はSP1をチェックインし、それがtrueの場合は、InProcessが0になるまで残りを無視することはできませんか?

秘訣は、InProcessを1に更新している間、読み取りをブロックすることです。これは、(SP内の)ステートメントが変更されたが他のトランザクションによってコミットされていないデータを読み取れないことを指定するSET TRANSACTION ISOLATION LEVELREADCOMMITTEDで実行できます。

お役に立てれば。

于 2009-12-03T10:50:37.897 に答える
1

一体なぜこれをC#で実行したいのですか?これはT-SQLに最適です!

 UPDATE 
     dbo.Students
 SET 
     TotalMarks = (some formula),
     IsTotalCalculated = 1
 WHERE 
     IsTotalCalulated = 0

1つのT-SQLステートメントで完了です。トランザクションスコープやデータのロードを前後にシャッフルする心配はありません。

OK、それで、あなたがあなたの現在のアプローチに固執しなければならないならば-あなたがすることができることはここにあります:

懸念事項:私の懸念は、処理する2つの行を選択するとすぐに、他のコンソールアプリインスタンスがこれらの2つの行を処理対象として選択しないようにすることです。私は何をすべきか?

テーブルを「非表示」にしてStudents、たとえば誰にもアクセスを許可せず、代わりにその上にあるビューを使用して、InProcess=0の行のみを表示するのはどうでしょうか。

CREATE VIEW dbo.StudentsView
AS
    SELECT (list of fields)
    FROM dbo.Students
    WHERE InProcess = 0

このように、生徒を読むためのリクエストは常に、現在処理されていない生徒のみを読みます。

于 2009-12-03T10:51:34.570 に答える
0

自分のやり方で物事を行う理由があると確信していますが、これが単なる例示的なサンプルではなく実際のテーブルである場合は、計算された合計列を持つビューを使用してみませんか?そうすれば、コンソールアプリで行を処理したり、行をロックしたりする必要がなくなります。

于 2009-12-03T10:28:26.777 に答える