Saya mengalami masalah konkurensi dengan sisipan saya dalam prosedur tersimpan. Bagian yang relevan dari prosedur ini adalah:
select @_id = Id from table1 where othervalue = @_othervalue
IF( @_id IS NULL)
BEGIN
insert into table1 (othervalue) values (@_othervalue)
select @_id = Id from table1 where othervalue = @_othervalue
END
Ketika kami menjalankan 3 atau 4 dari proc yang disimpan ini secara bersamaan, kami mendapatkan beberapa insert sesekali.
Saya berencana memperbaiki ini seperti ini:
insert into table1 (othervalue)
select TOP(1) @_othervalue as othervalue from table1 WITH(UPDLOCK)
where NOT EXISTS ( select * from table1 where othervalue = @_othervalue )
select @_id = Id from table1 where othervalue = @_othervalue
Pertanyaannya adalah, apakah cara memasukkan secara bersamaan tanpa duplikat di server sql? Fakta bahwa saya harus menggunakan TOP hanya untuk memasukkan sekali mengganggu saya.
Jawaban:
Anda bisa menggunakan pernyataan gabungan dengan
serializable
petunjuk.sumber
insert ... where not exist ...
pola dan menemukan bahwa Anda bisa mendapatkan kebuntuan dan pelanggaran utama sehingga diperlukan untuk menggunakan updlock dan serial. Saya kemudian menguji pernyataan gabungan dan berpikir itu akan menangani hal-hal yang sedikit lebih baik dan itu terjadi karena di sana tidak ada deadlock tetapi saya masih harus menggunakan serializable untuk tidak memiliki pelanggaran utama.Jika Anda tidak ingin duplikat pada kolom 'nilai lain', Anda dapat melakukannya dengan membuat
unique constraint
kolom tersebut. Kueri akan menjadi:Ini akan mengembalikan kesalahan jika kueri mencoba memasukkan nilai duplikat ke kolom 'nilai lain'.
sumber
Gunakan batasan unik seperti rekomendasi @StanleyJohns. Kemudian gunakan BEGIN TRY END TRY di sekitar pernyataan insert Anda.
sumber