ZengCode.Com (The Thai Php Framework)  


Home   Download   Manual   About us    

Facebook   


MAIN MENU
เขียนโปรแกรมบน iPhone ด้วย MonoTouch
News
Php Tips
Ubuntu
Spring+Strut+Hibernate
Android Programming
Design Pattern By PHP
C# Design Pattern
Linux Quick Tips
C# Tips & Technique
C# using Linq น่าใช้จริงๆ
Java & JavaScript Tips
MAVEN
Database & SQL
ZengCode Framework Guide
Mac OSx
Zeng Code Code
Programming
IPhone (Tips and Trick)

Download เอกสารที่น่าสนใจ

     SQL: Locking and Deadlock  (2009-04-01)

SQL: Locking and Deadlock

วันนี้จะมาเล่าถึง Lock พื้นฐาน 3 ประเภทคือ
1. Share Lock (ไม่ต้องระบุ) เป็น lock ที่ถูกใช้ในการ select
2. Update Lock (updlock) เป็น lock ที่ถูกใช้ตอนที่จะมีการแก้ไขข้อมูล เช่น update
3. Exclusive Lock (xlock) เป็น lock ที่ถูกใช้เมื่อข้อมูลนั้นมีการแก้ไขแล้ว

การใช้ lock ประเภทต่างๆนั้นจะพูดถึงการใช้ใน transaction ที่มี isolation level เป็น serializable
เพราะว่า ที่ level นี้จะเหมือนกับการใส่ holdlock เพิ่มลงไปในทุก query ที่ใช้
holdlock นั้นหมายถึง ให้ถือ lock ใดๆที่ใช้ตอนนั้นไปจนกว่าจะจบ transaction ถ้าไม่ใส่ holdlock มันก็จะถือ lock ที่ใช้ไว้แค่สิ้นสุด statement ของการ query เท่านั้น

ตัวอย่างการอธิบาย lock ต่างๆ
- share lock จะใช้ร่วมกับ share lock และ update lock ได้
- update lock จะใช้ร่วมกับ share lock ได้เท่านั้น
- exclusive lock ไม่สามารถใช้ ร่วมกับ lock ใดๆได้

เช่น
Begin T1
Begin T2

T1.Select * From Table -- ข้อมูลที่ถูก Selct จะติด share lock
T2.Select * From Table -- ข้อมูลที่จะถูก Selct จะติด share lock อยู่แต่สามารถ Select ออกมาได้เพราะว่า การ Select ใช้ share lock ซึ่งจะใช้ร่วมกับ share lock ได้

End T2
End T1

อีกตัวอย่าง
Begin T1
Begin T2

T1.Select * From Table with (updlock)-- ข้อมูลที่ถูก Selct จะติด update lock
T2.Select * From Table -- ข้อมูลที่จะถูก Selct จะติด update lock อยู่แต่สามารถ Select ออกมาได้เพราะว่า การ Select ใช้ share lock ซึ่งจะใช้ร่วมกับ update lock ได้

End T2
End T1

อีกตัวอย่าง
Begin T1
Begin T2

T1.Select * From Table -- ข้อมูลที่ถูก Selct จะติด share lock
T2.Select * From Table with (updlock) -- ข้อมูลที่จะถูก Selct จะติด share lock อยู่แต่สามารถ Select ออกมาได้เพราะว่า การ Select นี้จะใช้ update lock ซึ่งจะใช้ร่วมกับ share lock ได้

End T2
End T1

อีกตัวอย่าง
Begin T1
Begin T2

T1.Select * From Table with (updlock) -- ข้อมูลที่ถูก Selct จะติด update lock
T2.Select * From Table with (updlock) -- ข้อมูลที่จะถูก Selct จะติด update lock อยู่ ไม่สามารถSelect ออกมาได้เพราะว่า การ Select นี้จะใช้ update lock ซึ่งจะใช้ร่วมกับ update lock ไม่ได้

End T2
End T1

อันนี้จะอธิบายเพิ่มเติมเรื่อง update lock
ตัวอย่างเช่นถ้ามี statement: Update Table1 Set Value=2 where ID = 1 ซึ่ง
พอ โปรแกรมมันรันถึงอันนี้ มันก็จะใส่ updlock ลงไปใน row ที่มี ID = 1 ซึ่งถ้า row นั้นไม่ได้ติด updlock หรือ xlock อยู่ มันก็จะใส่ updlock ของมันลงไปสำเร็จ
พอใส่แล้วจะเซตค่า Value=2 พอเปลี่ยนเสร็จ updlock นั้นจะถูกเปลี่ยนเป็น xlock ทันที คราวนี้ Transaction อื่นๆไม่มาสามรถใช้ row นี้ได้จนกว่า Transaction ที่เป็นเจ้าของ lock นี้จะเสร็จงาน(Committed, Rollback)

คงจะพอเข้าใจ lock
ต่อมาก็จะพูดถึง deadlock
รูปแบบทั้วไปของ deadlock ก็เช่น

T1.Update a
T2.Ubdate b
T1.Update b
T2.Update a -- deadlock

จะเห็นว่า T1 มี a ต้องการ b แต่ T2 มี b ต้องการ a แบบนี้ก็เกิด deadlock
วิธีแก้คือ
เรียงลำดับการใช้งานให้เป็นทิศทางเดียวกันเช่นใช้ a ก่อนเสมอแล้วใช้ b

อีกรูปแบบ
มีโปรแกรมหนึ่งมีลำดับการทำงานดังนี่

Begin Transaction
1. Select a
2. Update a
End Transaction

เมื่อมีคนสองคนรันโปรแกรมนี้พร้อมๆกันอาจจะเกิดลำดับการทำงานดังนี้
T1.Select a
T2.Select a
T1.Update a
T2.Update a -- deadlock

ตอนแรกเห็นแบบนี้ว่ามีการใช้แต่ค่า a มันจะ deadlock ได้อย่างไร
งั้นมาดูกลไกลึกๆ
-T1 ใส่ sharelock ลง a
-T2 ใส่ sharelock ลง a ใส่ได้เพราะ sharelock ใช้ร่วมกันได้
-T1 เปลี่ยน sharelock เป็น updlock เพราะจะอับเดท แล้วก็เปลี่ยนเป็น xlock เมื่อเปลี่ยนค่า
-T2 จะอับเดทเลยใส่ updlock แต่มันใส่ไม่ได้เพราะติด xlock จาก T1,T1 จะ Committed เพื่อจบงานก็ไม่ได้เพราะมันจะเปลี่ยนค่าถ้า T2 อ่านมาใหม่จะไม่ได้เหมือนอ่านครั้งแรก แต่ว่า Isolation เป็น Serializable ซึ่งจะต้องไม่เกิด Nonrepeatable read ก็เลย raise error deadlock

วิธีการแก้
ใส่ with (updlock) ลงใน select statement ทุก statement ที่จะตามด้วยการ update ค่าของ statement ที่ select ตอนแรก

T1.Select a with (updlock) -- ทำสำเร็จ
T2.Select a with (updlock) -- คราวนี้ มันจะคอยจน T1 ทำงานสำเร็จก่อนซึ่งมันยังไม่ select ค่าอะไรออกมา เพราะมันติด updlock ซึ่งใช้ร่วมกับ udplock ไม่ได้ มันจะ pause ตัวเองแล้วให้ T1 ทำต่อ
T1.Update a -- ทำสำเร็จ
T2.Select a with (updlock) -- ทำต่อหลังจาก T1 เสร็จแล้ว
T2.Update a -- ทำสำเร็จ

ไม่เกิด deadlock แล้ว

สรุปทางลดปัญหา Deadlock คือ
1. เรียงลำดับการใช้
2. ใส่ updlock

ขอบคุณที่มา http://www.bloggang.com/viewdiary.php?id=chaizzz&month=03-2006&date=08&group=1&gblog=8

 
 


Comment

Delphia  (23 สิงหาคม 2554)   
IP : 80.68.89.167
At last! Someone who understands! Thanks for potsing!


Tommy  (03 มิถุนายน 2553)   
IP : 203.155.158.4

ขอบคุณมากๆๆครับ เป็นบทความที่ดีมากครับ อ่านแล้วเข้าใจดี

Thanks
http://www.kindelreaderdx.com


Name
Comment
Security CodeCAPTCHA Image

web hit counter

This page took 0.080281 seconds to load.