割り当にシリアル番号をクライアントのプールからのシリアル番号
-
13-09-2019 - |
質問
私はsqlサーバーテーブルのライセンスキー/シリアル番号テーブル構造のようなもの;
[
RecordId int,
LicenceKey string,
Status int (available, locked, used, expired etc.)
AssignedTo int (customerId)
....
]
を通してASP.NET 申請の場合、ユーザの判断を購入ライセンスをクリックし、受け入れボタン、予約する必要があるライセンスキーに作業を行うことができます。私のアプローチは、 選択のトップ1licenceKeyからKeysTable場の状況=り 更新KeysTableセット状態=ロック そのキーに戻ります。
私に関しては、まasp.net スレッドがアクセスの同じレコードを返します同じlicencekey.何だとお考えの練習を行なうような課題が?いもの形はパターンをこのような問題なのか。が使用lock()諸表さい。
私はまさにSqlサーバーを使、2005年には継続のためのデータにアクセス、DataLayer、BusinessLayerとAsp.Net GUI.
感謝
解決
りょうを使用する必要がなく、明示的なロック取引のこと。
ご存の手順を更新することができテーブルを取得するライセンスキーを単一の原子操作を用いた OUTPUT
項お 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'
他のヒント
あなたが何を言ってるのか実現するには、シリアライザブルトランザクションを使用することをお勧めします。これを行うには、このパターンに従います。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
--Execute select
--Execute update
COMMIT TRANSACTION
しかし、なぜあなたは、すべての可能なライセンスキーを持つテーブルを持っているのですか?鍵生成アルゴリズムを持っていないのはなぜユーザーはそれを購入する場合、その後、新しいキーを作成する?
また、1つのスレッドだけ一度にアクセス権を持っていることを確認するために、取引に加えて、(SQLで)ロックを使用してみてください可能性があります。
私は、アプリケーションロックがここで助けになることを信じています。
私は、そうでない場合は、常に競合状態のいくつかの並べ替えが存在しますので、あなたが実際に、あなたはそれのために照会されている同じストアドプロシージャでは使用できないようにキーをマークするべきだと思います。手動でテーブルをロックすることは良い練習の私見ではありません。
あなたが持っている場合は、は2あなたは、あなたが新しいキーを照会するときように、あなたは、時間(例えば30分)の指定された期間のための鍵を予約するという概念を導入する可能性(例えば航空会社のチケット予約のような)プロセスを上演しました同時に、それを予約します。
EDIT:あなたが唯一のプロセスがデータベースを変更しようとしていることを保証することができれば、ビジネスロジック内のロックはおそらく動作しますが、好ましくは単一のストアドプロシージャでは、データベースレベルでそれを行うためにはるかに優れています。あなたは、トランザクション・レベルを設定し、@Adamロビンソンが彼の答えで提案されているのと同様に、データベースにトランザクションを使用する必要があり、それを正しく行うには。