0

ライセンス キー/シリアル番号の SQL サーバー テーブルがあります。テーブル構造は次のようなものです。

[
RecordId int,
LicenceKey string,
Status int (available, locked, used, expired etc.)
AssignedTo int (customerId)
....
]

ASP.NET アプリケーションを使用して、ユーザーが同意ボタンをクリックしてライセンスを購入することを決定した場合、ユーザーのライセンス キーを予約する必要があります。私のアプローチは、KeysTable から上位 1 つの licenceKey を選択します。ここで、Status = available を更新します。KeysTable Set status = locked にしてから、キーをアプリケーションに戻します。

私の懸念は、2 つの asp.net スレッドが同じレコードにアクセスし、同じライセンス キーを返す場合です。そのような割り当てを行うベストプラクティスは何だと思いますか? この種の問題に対するよく知られたアプローチまたはパターンはありますか? 必要な場合、lock() ステートメントをどこで使用しますか?

私はSql Server 2005、データアクセス用のストアドプロシージャ、DataLayer、BusinessLayer、およびAsp.Net GUIを使用しています。

ありがとう

4

4 に答える 4

4

この場合、明示的なロックやトランザクションを使用する必要はおそらくありません。

ストアド プロシージャでは、ステートメントでOUTPUT句を使用することにより、1 回のアトミック操作でテーブルを更新し、ライセンス キーを取得できます。UPDATE

このようなもの:

UPDATE TOP (1) KeysTable
SET Status = 'locked'
OUTPUT INSERTED.LicenseKey
-- if you want more than one column...
-- OUTPUT INSERTED.RecordID, INSERTED.LicenseKey
-- if you want all columns...
-- OUTPUT INSERTED.*
WHERE Status = 'available'
于 2009-04-22T13:21:48.963 に答える
1

あなたが話していることを達成するには、シリアル化可能なトランザクションを使用する必要があります。これを行うには、次のパターンに従います。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION

--Execute select
--Execute update

COMMIT TRANSACTION

しかし、考えられるすべてのライセンス キーを表にまとめたのはなぜでしょうか。キー生成アルゴリズムを用意して、ユーザーが購入したときに新しいキーを作成しないのはなぜですか?

于 2009-04-22T12:55:06.123 に答える
0

トランザクションに加えて (SQL で) ロックを使用して、一度に 1 つのスレッドのみがアクセスできることを確認することもできます。

ここでは、アプリケーション ロックが役立つと思います。

于 2009-04-22T13:03:39.287 に答える
0

キーをクエリしているのと同じストアド プロシージャでキーを使用不可として実際にマークする必要があると思います。そうしないと、常にある種の競合状態が発生するためです。テーブルを手動でロックすることは、良い習慣ではありません。

2 段階のプロセス (航空券の予約など) がある場合は、指定された期間 (30 分など) の間キーを予約するという概念を導入できます。これにより、新しいキーをクエリするときに、同時に。

編集: 1 つのプロセスのみがデータベースを変更することを保証できる場合、ビジネス ロジックのロックはおそらく機能しますが、データベース レベルで、できれば単一のストアド プロシージャで行う方がはるかに優れています。@Adam Robinsonが回答で提案したように、正しく行うには、トランザクションレベルを設定し、データベースでトランザクションを使用する必要があります。

于 2009-04-22T12:54:45.643 に答える