Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Apakah pernyataan SQL Server tunggal atom dan konsisten?

Saya telah beroperasi dengan asumsi bahwa satu pernyataan di SQL Server konsisten

Anggapan itu salah. Dua transaksi berikut memiliki semantik penguncian yang identik:

STATEMENT

BEGIN TRAN; STATEMENT; COMMIT

Tidak ada perbedaan sama sekali. Pernyataan tunggal dan komit otomatis tidak mengubah apa pun.

Jadi menggabungkan semua logika menjadi satu pernyataan tidak membantu (jika ya, itu tidak sengaja karena rencananya berubah).

Mari kita perbaiki masalah yang ada. SERIALIZABLE akan memperbaiki ketidakkonsistenan yang Anda lihat karena ini menjamin bahwa transaksi Anda berperilaku seolah-olah mereka dieksekusi secara single-threaded. Secara setara, mereka berperilaku seolah-olah mereka dieksekusi secara instan.

Anda akan mendapatkan jalan buntu. Jika Anda setuju dengan pengulangan percobaan, Anda sudah selesai pada tahap ini.

Jika Anda ingin menginvestasikan lebih banyak waktu, terapkan petunjuk penguncian untuk memaksa akses eksklusif ke data yang relevan:

UPDATE Gifts  -- U-locked anyway
SET GivenAway = 1
WHERE GiftID = (
   SELECT TOP 1 GiftID
   FROM Gifts WITH (UPDLOCK, HOLDLOCK) --this normally just S-locks.
   WHERE g2.GivenAway = 0
    AND (SELECT COUNT(*) FROM Gifts g2 WITH (UPDLOCK, HOLDLOCK) WHERE g2.GivenAway = 1) < 5
   ORDER BY g2.GiftValue DESC
)

Anda sekarang akan melihat pengurangan konkurensi. Itu mungkin baik-baik saja tergantung pada beban Anda.

Sifat masalah Anda membuat pencapaian konkurensi menjadi sulit. Jika Anda memerlukan solusi untuk itu, kami perlu menerapkan teknik yang lebih invasif.

Anda dapat menyederhanakan UPDATE sedikit:

WITH g AS (
   SELECT TOP 1 Gifts.*
   FROM Gifts
   WHERE g2.GivenAway = 0
    AND (SELECT COUNT(*) FROM Gifts g2 WITH (UPDLOCK, HOLDLOCK) WHERE g2.GivenAway = 1) < 5
   ORDER BY g2.GiftValue DESC
)
UPDATE g  -- U-locked anyway
SET GivenAway = 1

Ini menghilangkan satu gabungan yang tidak perlu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SYSDATETIME() Contoh di SQL Server (T-SQL)

  2. 4 Alasan Mengapa Anda Harus Memprioritaskan Pemantauan Database dalam Perencanaan 2020

  3. Nilai NULL di dalam klausa NOT IN

  4. Sintaks salah di dekat kata kunci 'dengan'...pernyataan sebelumnya harus diakhiri dengan titik koma

  5. Kembalikan nilai dari perintah Sisipkan SQL Server menggunakan c #