กระทู้เก่าบอร์ด อ.Yeadram
2,713 9
URL.หัวข้อ /
URL
วิธีการ Lock record ก่อนบันทึกข้อมูล
เนื่องจากในระบบ client มีการชนกันของข้อมูลเป็นประจำ ผมเลยต้องการที่ตรวจสอบก่อนว่า record ของข้อมูลที่ผมกำลังจะไปบันทึกข้อมูลมีคนไหนกำลังแก้ไขอยู่หรือเปล่า
- ถ้าไม่มีการแก้ไขอยู่ ผมต้องการที่จะ Lock ข้อมูล พร้อมกับบันทึกข้อมูลทันที (คิดว่าใช้เวลาเพียง 0.1 วินาที) หลังจากนั้นก็ UnLock ข้อมูลทันทีที่ Update ข้อมูลเสร็จ
- ถ้ามีคนกำลังแก้ไขอยู่ อยากให้วนลูปซักประมาณ 3 วินาที จนกว่าจะ Lock ข้อมูลสำเร็จ (เผื่อมีคนอื่นกำลังแก้ไขข้อมูลอยู่เหมือนกัน) ถ้า Lock สำเร็จก็ Update ข้อมูล ถ้าไม่สำเร็จ ก็ขึ้น Error Message แจ้งเตือน
ไม่รู้คำถามโดนป่าวครับ (โดยเฉพาะคุณ U&ME)
(ผมใช้วิธีแบบ Unbound และถ้า connect data เป็นแบบ ADO ได้ยิ่งดี เพราะบางครั้งถ้า Update ข้อมูลได้ไม่ครบ สามารถทำ Rollback กลับได้ด้วย )
ขอบคุณครับ
- ถ้าไม่มีการแก้ไขอยู่ ผมต้องการที่จะ Lock ข้อมูล พร้อมกับบันทึกข้อมูลทันที (คิดว่าใช้เวลาเพียง 0.1 วินาที) หลังจากนั้นก็ UnLock ข้อมูลทันทีที่ Update ข้อมูลเสร็จ
- ถ้ามีคนกำลังแก้ไขอยู่ อยากให้วนลูปซักประมาณ 3 วินาที จนกว่าจะ Lock ข้อมูลสำเร็จ (เผื่อมีคนอื่นกำลังแก้ไขข้อมูลอยู่เหมือนกัน) ถ้า Lock สำเร็จก็ Update ข้อมูล ถ้าไม่สำเร็จ ก็ขึ้น Error Message แจ้งเตือน
ไม่รู้คำถามโดนป่าวครับ (โดยเฉพาะคุณ U&ME)
(ผมใช้วิธีแบบ Unbound และถ้า connect data เป็นแบบ ADO ได้ยิ่งดี เพราะบางครั้งถ้า Update ข้อมูลได้ไม่ครบ สามารถทำ Rollback กลับได้ด้วย )
ขอบคุณครับ
9 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R07409
ค้นดูหมดแล้วครับ ยังไม่โดนครับ
ผมค้นหาโดยใช้ คีย Lock,Update, ADO,
มีอธิบายคร่าวๆ แต่ไม่มีหลักปฏิบัติแบบเข้าใจน่ะครับ
ผมค้นหาโดยใช้ คีย Lock,Update, ADO,
มีอธิบายคร่าวๆ แต่ไม่มีหลักปฏิบัติแบบเข้าใจน่ะครับ
3 @R07411
ไม่เต็มใจหาหรือเปล่า
http://www.thai-access.com/yeadram_view.php?topic_id=1705
http://www.thai-access.com/yeadram_view.php?topic_id=1705
4 @R07413
คุณ U&ME ครับ ผมไม่เห็นมีตรงไหนที่มัน Lock ข้อมูลเลยครับ
ตัวอย่างเช่น
รหัสสินค้า A-001 สมมุติปัจจุบันมียอดคงเหลือ 100 ชิ้น
ระหว่างนั้น User1 คียข้อมูลซื้อสินค้า A-001 จำนวน 10 ตัว ผมก็ต้องการจะ Update ข้อมูล โดยเอา 100 + 10 ก็จะได้ยอดคงเหลือเป็น 110 ชิ้น
ปัญหาคือในขณะเดียวกัน ถ้ามี User2 กำลังคีย์ขายข้อมูลสินค้า A-001 จำนวน 50 ชิ้นในเวลาเดียวกัน ถ้า User1 ไม่สามารถ Lock Record ที่กำลังแก้ไขอยู่ได้ก็จะเกิดปัญหาว่า ยอดคงเหลือหาก User2 คีย์ได้สำเร็จ จะกลายเป็น 100 - 50 = 50 แต่ที่ถูกต้องควรจะเป็น 110 - 50 = 60 แถมยังเกิดปัญหา Record ซ้อนกัน และมี Error ขึ้นมาให้ Drop Change อีกด้วย
สิ่งที่ผมต้องการคือ ทำยังไงให้เราสามารถ Lock Record ก่อนที่จะบันทึกข้อมูลลงไป เพื่อกันไม่ให้ User คนอื่นเข้ามาบันทึกข้อมูลซ้ำได้ และหลังจากเราบันทึกข้อมูลเสร็จก็ให้เราสามารถปลดล็อก เพื่อให้คนอื่นสามารถเข้ามา Lock และบันทึกข้อมูลได้
ขออีกครั้งนะครับ
ตัวอย่างเช่น
รหัสสินค้า A-001 สมมุติปัจจุบันมียอดคงเหลือ 100 ชิ้น
ระหว่างนั้น User1 คียข้อมูลซื้อสินค้า A-001 จำนวน 10 ตัว ผมก็ต้องการจะ Update ข้อมูล โดยเอา 100 + 10 ก็จะได้ยอดคงเหลือเป็น 110 ชิ้น
ปัญหาคือในขณะเดียวกัน ถ้ามี User2 กำลังคีย์ขายข้อมูลสินค้า A-001 จำนวน 50 ชิ้นในเวลาเดียวกัน ถ้า User1 ไม่สามารถ Lock Record ที่กำลังแก้ไขอยู่ได้ก็จะเกิดปัญหาว่า ยอดคงเหลือหาก User2 คีย์ได้สำเร็จ จะกลายเป็น 100 - 50 = 50 แต่ที่ถูกต้องควรจะเป็น 110 - 50 = 60 แถมยังเกิดปัญหา Record ซ้อนกัน และมี Error ขึ้นมาให้ Drop Change อีกด้วย
สิ่งที่ผมต้องการคือ ทำยังไงให้เราสามารถ Lock Record ก่อนที่จะบันทึกข้อมูลลงไป เพื่อกันไม่ให้ User คนอื่นเข้ามาบันทึกข้อมูลซ้ำได้ และหลังจากเราบันทึกข้อมูลเสร็จก็ให้เราสามารถปลดล็อก เพื่อให้คนอื่นสามารถเข้ามา Lock และบันทึกข้อมูลได้
ขออีกครั้งนะครับ
5 @R07414
งั้นก็เอาอย่างงี้ละกัน
ตารางสินค้าก็ให้สร้าง field ขึ้นมา เพื่อใช้เป็นตัวบอกว่า ข้อมูลเร็คคอร์ดนี้กำลังใช้งานอยู่
เมื่อผู้ใช้คีย์ข้อมูลสิ้นค้านั้นเข้าไปก็ให้ตรวจ field นี้ก่อนเสมอ ว่าสามารถขายสินค้าตัวนี้ได้หรือไม่
*** อย่าลืม ควรใช้คู่กับการ Rollback ตามกระทู้ที่ให้ไปก่อนหน้า เพราะถ้าเกิดข้อผิดพลาดในการบันทึกเราจะได้สามารถย้อนกลับไปยังจุดเริ่มต้นได้
ตารางสินค้าก็ให้สร้าง field ขึ้นมา เพื่อใช้เป็นตัวบอกว่า ข้อมูลเร็คคอร์ดนี้กำลังใช้งานอยู่
เมื่อผู้ใช้คีย์ข้อมูลสิ้นค้านั้นเข้าไปก็ให้ตรวจ field นี้ก่อนเสมอ ว่าสามารถขายสินค้าตัวนี้ได้หรือไม่
*** อย่าลืม ควรใช้คู่กับการ Rollback ตามกระทู้ที่ให้ไปก่อนหน้า เพราะถ้าเกิดข้อผิดพลาดในการบันทึกเราจะได้สามารถย้อนกลับไปยังจุดเริ่มต้นได้
6 @R07415
ขอแสดงความคิดเห็นด้วยแล้วกัน... ต้องบอกก่อนว่าผมไม่ได้ใช้ unbound form ครับ เลยไม่แน่ใจว่าวิธีที่ผมจะบอกนี้ ใช่วิธีที่ปกติเขาทำกันหรือไม่ แต่คิดว่ามันควรเป็นอย่างนี้
1) กำหนด IsolationLevel property ของ ADO's Connection object ให้เป็นอย่างน้อยที่ระดับ adXactRepeatableRead (มีค่าเป็น 65536)
2) Begin Transaction
3) อ่านเรคอร์ดจากเทเบิล ซึ่งเป็นเรคอร์ดเดียวกับที่แสดงบนหน้าจอ เพราะเนื่องจากเราใช้ IsolationLevel ตามที่กำหนดข้างต้น ระบบน่าจะล็อคไม่ให้คนอื่นมาอ่านเรคอร์ดนี้ได้อีกจนกว่าเราจะ Commit หรือ Rollback Transaction แต่อันนี้ต้องลองครับ เพราะไม่รู้ว่า Jet Engine จะสนับสนุน IsolationLevel นี้หรือไม่ อาจทดลองโดยหลังจากกำหนดในขั้นที่ 1) แล้ว ให้อ่าน IsolationLevel อีกที ถ้าค่าที่ได้ได้มากกว่าหรือสูงกว่า ก็ถือว่าโอเคครับ แต่ถ้าต่ำกว่า ก็แปลว่าไม่สนับสนุน ถ้าไม่สนับสนุน การอัดเดตก็มีโอกาสเกิด error บอกมาว่าคนอื่นเขาอัพเดตไปก่อนที่เราจะอัพเดตแล้ว
4) ตรวจว่าทุกฟิลด์บนหน้าจอกับในเทเบิลมีความแตกต่างกันหรือไม่ ขั้นนี้คือสิ่งที่คุณต้องลงแรงเมื่อคุณใช้ unbound form
5) ถ้ามีความแตกต่าง ก็ต้องบอกผู้ใช้ว่าไม่เหมือนกันแล้ว ตรงนี้ก็เอาข้อมูลที่ใหม่กว่าจากเทเบิลไปแสดงแทนของเดิมแล้วยกเลิกก?รอัพเดตและ Rollback Transaction
6) ถ้าไม่แตกต่าง ก็ค่อยอัพเดต
7) Commit Transaction
สำหรับเรื่องการ retry ในกรณีเรคอร์ดนั้นมีคนอื่นล็อคอยู่ คุณลองดู http://msdn.microsoft.com/en-us/library/ms681754%28VS.85%29.aspx parameter ที่ใช้กำหนดคือ Jet OLEDB:Lock Delay และ Jet OLEDB:Lock Retry
ทั้งหมดนี้คุณต้องไปลองเองนะครับ เพราะมันแค่เคยผ่านตาผมเท่านั้น ยังไม่เคยใช้สักครั้ง
1) กำหนด IsolationLevel property ของ ADO's Connection object ให้เป็นอย่างน้อยที่ระดับ adXactRepeatableRead (มีค่าเป็น 65536)
2) Begin Transaction
3) อ่านเรคอร์ดจากเทเบิล ซึ่งเป็นเรคอร์ดเดียวกับที่แสดงบนหน้าจอ เพราะเนื่องจากเราใช้ IsolationLevel ตามที่กำหนดข้างต้น ระบบน่าจะล็อคไม่ให้คนอื่นมาอ่านเรคอร์ดนี้ได้อีกจนกว่าเราจะ Commit หรือ Rollback Transaction แต่อันนี้ต้องลองครับ เพราะไม่รู้ว่า Jet Engine จะสนับสนุน IsolationLevel นี้หรือไม่ อาจทดลองโดยหลังจากกำหนดในขั้นที่ 1) แล้ว ให้อ่าน IsolationLevel อีกที ถ้าค่าที่ได้ได้มากกว่าหรือสูงกว่า ก็ถือว่าโอเคครับ แต่ถ้าต่ำกว่า ก็แปลว่าไม่สนับสนุน ถ้าไม่สนับสนุน การอัดเดตก็มีโอกาสเกิด error บอกมาว่าคนอื่นเขาอัพเดตไปก่อนที่เราจะอัพเดตแล้ว
4) ตรวจว่าทุกฟิลด์บนหน้าจอกับในเทเบิลมีความแตกต่างกันหรือไม่ ขั้นนี้คือสิ่งที่คุณต้องลงแรงเมื่อคุณใช้ unbound form
5) ถ้ามีความแตกต่าง ก็ต้องบอกผู้ใช้ว่าไม่เหมือนกันแล้ว ตรงนี้ก็เอาข้อมูลที่ใหม่กว่าจากเทเบิลไปแสดงแทนของเดิมแล้วยกเลิกก?รอัพเดตและ Rollback Transaction
6) ถ้าไม่แตกต่าง ก็ค่อยอัพเดต
7) Commit Transaction
สำหรับเรื่องการ retry ในกรณีเรคอร์ดนั้นมีคนอื่นล็อคอยู่ คุณลองดู http://msdn.microsoft.com/en-us/library/ms681754%28VS.85%29.aspx parameter ที่ใช้กำหนดคือ Jet OLEDB:Lock Delay และ Jet OLEDB:Lock Retry
ทั้งหมดนี้คุณต้องไปลองเองนะครับ เพราะมันแค่เคยผ่านตาผมเท่านั้น ยังไม่เคยใช้สักครั้ง
7 @R07416
สุดยอดความรู้ครับ แต่ไม่รู้จะทำได้หรือเปล่าครับ ขอบคุณครับ
8 @R07436
เห็นท่านอาจารย์ในบอร์ดนี้ที่มาจากบอร์ดเดิมของอาจารย์สุภาพก็หลายคน แต่ไม่รู้ว่าอาจารย์ BadMan ท่านไปไหนแล้วคิดถึงจัง...
9 @R07441
ผมคิดถึงอาจารย์ BadMan ด้วย
และขอบคุณอาจารย์สันติสุขและทุกท่านที่ช่วยกันดูแลสังคมด้วย :)
และขอบคุณอาจารย์สันติสุขและทุกท่านที่ช่วยกันดูแลสังคมด้วย :)
Time: 0.3280s
_______________________
อยากให้ลองค้นดูก่อนครับ ประมาณว่าเมื่อเร็ว ๆ นี้แหละครับ
ความน่าสนใจของคำถามนี้อยู่ในระดับที่ดีครับ คือสามารถนำไปแก้ปัญหาได้ในสภาพการทำงานกับข้อมูลที่มีผู้ใช้หลายคน