สมมติว่าคุณมีรหัสต่อไปนี้ (โปรดอย่าสนใจว่ามันแย่มาก):
BEGIN TRAN;
DECLARE @id int
SELECT @id = id + 1 FROM TableA;
UPDATE TableA SET id = @id; --TableA must have only one row, apparently!
COMMIT TRAN;
-- @id is returned to the client or used somewhere else
ในสายตาของฉันนี่ไม่ใช่การจัดการภาวะพร้อมกันอย่างเหมาะสม เพียงเพราะคุณมีการทำธุรกรรมไม่ได้หมายความว่าคนอื่นจะไม่อ่านค่าเดียวกันกับที่คุณทำก่อนที่คุณจะได้รับการปรับปรุงของคุณ
ตอนนี้ปล่อยให้รหัสตามที่เป็นอยู่ (ฉันตระหนักดีว่านี่คือการจัดการที่ดีกว่าเป็นคำสั่งเดียวหรือดียิ่งขึ้นโดยใช้คอลัมน์ autoincrement / เอกลักษณ์) สิ่งที่แน่ใจว่าวิธีที่จะทำให้มันจัดการพร้อมกันอย่างถูกต้องและป้องกันเงื่อนไขการแข่งขัน ค่า id หรือไม่
ฉันค่อนข้างแน่ใจว่าการเพิ่มคำWITH (UPDLOCK, HOLDLOCK)
ใน SELECT จะทำเคล็ดลับ ระดับ SERIALIZABLE แยกธุรกรรมจะดูเหมือนว่าจะทำงานได้เป็นอย่างดีเพราะมันปฏิเสธคนอื่นที่จะอ่านสิ่งที่คุณทำจน tran ที่มีมากกว่า ( UPDATE : นี้เป็นเท็จคำตอบที่ดูมาร์ติน.) มันเป็นเรื่องจริงเหรอ? พวกเขาทั้งสองจะทำงานได้ดีเท่าเทียมกันหรือไม่ เป็นที่ต้องการมากกว่าหนึ่งอื่น ๆ ?
ลองนึกภาพการทำสิ่งที่ถูกกฎหมายมากกว่าการอัปเดต ID - การคำนวณบางอย่างจากการอ่านที่คุณต้องอัปเดต อาจมีหลายตารางที่เกี่ยวข้องซึ่งบางส่วนที่คุณจะเขียนและอื่น ๆ ที่คุณจะไม่ การปฏิบัติที่ดีที่สุดที่นี่คืออะไร?
เมื่อเขียนคำถามนี้ฉันคิดว่าคำแนะนำการล็อคดีกว่าเพราะคุณเพียงล็อคตารางที่คุณต้องการ แต่ฉันขอขอบคุณที่ทุกคนป้อนข้อมูล
ป.ล. และไม่ฉันไม่ทราบคำตอบที่ดีที่สุดและต้องการได้รับความเข้าใจที่ดีขึ้น! :)
update
ซึ่งอาจเป็นไปตามข้อมูลที่ล้าสมัยหรือไม่? หากภายหลังคุณสามารถใช้rowversion
คอลัมน์เพื่อตรวจสอบว่าแถวที่จะอัปเดตไม่ได้เปลี่ยนไปตั้งแต่อ่านแล้วหรือไม่