Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Một câu lệnh SQL Server duy nhất có phải là nguyên tử và nhất quán không?

Tôi đã hoạt động với giả định rằng một câu lệnh duy nhất trong SQL Server là nhất quán

Giả định đó là sai. Hai giao dịch sau có ngữ nghĩa khóa giống hệt nhau:

STATEMENT

BEGIN TRAN; STATEMENT; COMMIT

Không có sự khác biệt nào cả. Các câu lệnh đơn và cam kết tự động không thay đổi bất kỳ điều gì.

Vì vậy, việc hợp nhất tất cả logic thành một câu lệnh không giúp ích được gì (nếu có thì đó là do tình cờ vì kế hoạch đã thay đổi).

Hãy khắc phục sự cố trong tầm tay. SERIALIZABLE sẽ khắc phục sự không nhất quán mà bạn đang thấy vì nó đảm bảo rằng các giao dịch của bạn sẽ hoạt động như thể chúng được thực hiện theo đường đơn. Tương tự, chúng hoạt động như thể chúng thực thi ngay lập tức.

Bạn sẽ gặp bế tắc. Nếu bạn đồng ý với một vòng lặp thử lại, bạn đã hoàn tất tại thời điểm này.

Nếu bạn muốn đầu tư thêm thời gian, hãy áp dụng các gợi ý khóa để buộc quyền truy cập độc quyền vào dữ liệu có liên quan:

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
)

Bây giờ bạn sẽ thấy đồng thời giảm. Điều đó có thể hoàn toàn ổn tùy thuộc vào tải của bạn.

Bản chất vấn đề của bạn khiến việc đạt được đồng thời trở nên khó khăn. Nếu bạn yêu cầu một giải pháp cho điều đó, chúng tôi sẽ cần áp dụng các kỹ thuật xâm lấn hơn.

Bạn có thể đơn giản hóa việc CẬP NHẬT một chút:

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

Thao tác này sẽ loại bỏ một tham gia không cần thiết.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nối các giá trị hàng T-SQL

  2. SET DATEFIRST - Đặt Ngày đầu tiên trong tuần trong SQL Server

  3. Khắc phục sự cố khi làm việc với ngày và giờ trong SQL Server

  4. Entity Framework Core 2.0:Cách định cấu hình lớp cơ sở trừu tượng một lần

  5. Các loại con trỏ máy chủ SQL - Sự khác biệt giữa con trỏ địa phương và toàn cầu là gì | Hướng dẫn sử dụng SQL Server / TSQL