ここに簡単な解決策があります。競合状態はありません。制限付きトランザクション分離レベルからのブロックはありません。しかし、おそらくT-SQL以外のSQLの方言では動作しません。
カタログ番号テーブルに割り当てられていないカタログ番号が入力されているようにするには、仕事で外的な力があると思います。
この技術はあなたのために働く必要があります:値を取得する「インターロック更新」と同じ種類の操作を行うだけで、のようなもの:
update top 1 CatalogNumber
set in_use = 1 ,
@newCatalogNumber = catalog_number
from CatalogNumber
where in_use = 0
はとにかく、次のストアドプロシージャは、ただ単に、それぞれの数をアップティック前のものを手渡す。より魅力的な値が必要な場合は、希望する値を得るために、選択した変換をインクリメント値に適用する計算列を追加します。
drop table dbo.PrimaryKeyGenerator
go
create table dbo.PrimaryKeyGenerator
(
id varchar(100) not null ,
current_value int not null default(1) ,
constraint PrimaryKeyGenerator_PK primary key clustered (id) ,
)
go
drop procedure dbo.GetNewPrimaryKey
go
create procedure dbo.GetNewPrimaryKey
@name varchar(100)
as
set nocount on
set ansi_nulls on
set concat_null_yields_null on
set xact_abort on
declare
@uniqueValue int
--
-- put the supplied key in canonical form
--
set @name = ltrim(rtrim(lower(@name)))
--
-- if the name isn't already defined in the table, define it.
--
insert dbo.PrimaryKeyGenerator (id)
select id = @name
where not exists (select *
from dbo.PrimaryKeyGenerator pkg
where pkg.id = @name
)
--
-- now, an interlocked update to get the current value and increment the table
--
update PrimaryKeyGenerator
set @uniqueValue = current_value ,
current_value = current_value + 1
where id = @name
--
-- return the new unique value to the caller
--
return @uniqueValue
go
それを使用する:@pkは EXEC @pk = dbo.GetNewPrimaryKey 'foobarに' のint型
宣言は、結果セットを返すか、返すために、それを国防省する
トリビアルを@pk選択 OUTPUTパラメータを使用して値を設定します。
ストアドプロシージャの3つのステップはすべて、トランザクション内にカプセル化されていますか?トランザクションに設定されている独立性レベルは何ですか? – Thomas
割り当てられたカタログ番号に隙間がある場合は、黙示録ですか?つまり、T1にカタログ番号が割り当てられてからエラーが発生した場合、そのカタログ番号がスキップされた場合にはロールバックされますか? –
申し訳ありませんが離れて私の自身の質問を監視できませんでした。だから、1)いいえ、彼らは現在、トランザクションで、ちょうど同じsprocの中で次々に実行されていません。 2)隙間は理想的ではないが、黙示録の –