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

Di tsql, apakah Sisipkan dengan pernyataan Pilih aman dalam hal konkurensi?

Seperti yang ditulis Paul:Tidak, ini tidak aman , yang ingin saya tambahkan bukti empiris:Buat tabel Table_1 dengan satu bidang ID dan satu record dengan nilai 0 . Kemudian jalankan kode berikut secara bersamaan di dua jendela kueri Management Studio :

declare @counter int
set @counter = 0
while @counter < 1000
begin
  set @counter = @counter + 1

  INSERT INTO Table_1
    SELECT MAX(ID) + 1 FROM Table_1 

end

Kemudian jalankan

SELECT ID, COUNT(*) FROM Table_1 GROUP BY ID HAVING COUNT(*) > 1

Di SQL Server 2008, satu ID saya (662 ) dibuat dua kali. Jadi, tingkat isolasi default yang diterapkan pada pernyataan tunggal adalah tidak cukup.

EDIT:Jelas, membungkus INSERT dengan BEGIN TRANSACTION dan COMMIT tidak akan memperbaikinya, karena tingkat isolasi default untuk transaksi masih READ COMMITTED , yang tidak cukup. Perhatikan bahwa menyetel tingkat isolasi transaksi ke REPEATABLE READ adalah juga tidak cukup. Satu-satunya cara untuk membuat kode di atas aman adalah menambahkan

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

di atas. Namun, ini terkadang menyebabkan kebuntuan dalam pengujian saya.

EDIT:Satu-satunya solusi yang saya temukan yang aman dan tidak menghasilkan kebuntuan (setidaknya dalam pengujian saya) adalah secara eksplisit mengunci tabel secara eksklusif (tingkat isolasi transaksi default sudah cukup di sini). Hati-hati meskipun; solusi ini mungkin membunuh kinerja:

...loop stuff...
    BEGIN TRANSACTION

    SELECT * FROM Table_1 WITH (TABLOCKX, HOLDLOCK) WHERE 1=0

    INSERT INTO Table_1
      SELECT MAX(ID) + 1 FROM Table_1 

    COMMIT
...loop end...


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Algoritma untuk menghindari injeksi SQL pada MSSQL Server dari kode C #?

  2. Cara Menonaktifkan Semua Pemicu di Database SQL Server

  3. OPSI (REKOMPILASI) Selalu Lebih Cepat; Mengapa?

  4. ASIN() Contoh di SQL Server

  5. Entity Framework Core 2.0:Cara mengonfigurasi kelas dasar abstrak sekali