Data Integrity Problems เป็นหนึ่งใน Database Issues ที่พบบ่อยที่สุดสำหรับ Rails Developers นอกจาก Proper Validation แล้ว Transaction Blocks ที่ออกแบบถูกต้อง Ensure ว่า Data ไม่ถูก Create หรือ Update แบบ Partial
แต่ Transactions อาจ Harm แอป — หรือแม้แต่ Take Down Database ทั้งหมด — เมื่อไม่ได้ Designed อย่างถูกต้อง
บทความนี้เสนอ Good Practices สำหรับทำงานกับ Transactions Tips ค่อนข้าง Simple แต่จะช่วยทำให้ Transactions ของคุณ Bulletproof, Readable, และ Relative Safe
Lets Dive In!
1. ใช้ Bang Methods ใน Rails เมื่อเป็นไปได้
ใน Rails Method Versions ที่มี ! ให้ Confidence ว่า Error จะ Raise เมื่อ Something Goes Wrong
เช่น Method #save มี Version save! คุณอาจอยากใช้ Version นี้ใน Controller หากไม่อยาก Raise Errors:
Approach ข้างบนไม่ทำงานดีใน Transactions ด้วย save เราไม่สามารถ Roll Back Process เมื่อ Error Raise นั่นคือเหตุผลสำคัญที่ต้องใช้ Version !:
ในข้างบน Transaction Succeeds แม้ Membership Record ไม่ถูก Create และเรา End Up กับ Messed-up Data Structure ใน Database
ถ้าใช้ Version ต่อไปนี้ Transaction Reverts เนื่องจาก Error ActiveRecord::RecordNotSaved:
2. จัดการ Errors ใน Rails Transactions อย่างถูกต้อง
เมื่อพูดถึง Errors ใน Transactions มี Rules เล็กน้อยที่คุณควร Respect ด้วยการ Follow Rules เหล่านี้ คุณจะได้ Code ที่ Readable และ Well-working ไม่สร้าง Confusion ระหว่าง Developers อื่น หรือ Weird Behavior ที่ยาก Debug
อย่า Rescue จาก ActiveRecord::StatementInvalid
ActiveRecord::StatementInvalid เป็น Special Error Raise เมื่อ Something บน Database Level Goes Wrong อย่า Rescue จาก Error นี้เลย คุณควร Explicitly Notified ทุกครั้งที่ Something Goes Wrong กับ Database Query
หลีกเลี่ยงโค้ดนี้:
ใช้ Rescue บน Level ที่ถูกต้อง
ถ้าใช้ Rescue บน Level ต่อไปนี้ คุณจะ Catch Error:
Transaction ไม่ Roll Back เพราะคุณ Catch Error ให้ Error Raise และ Catch นอก Transaction Block:
ใน Approach ข้างบน Transaction Roll Back ในกรณี Error และคุณ Catch Error นี่คือ Right Approach Catch Errors ที่ Raise ภายใน Transactions โดยไม่ Overwrite Transaction Behavior
อย่า Catch Generic Errors
คุณควรหลีกเลี่ยง Catch Generic Errors เหมือน StandardError หรือ ArgumentError นี่ก็คือ General Rule สำหรับ Readable และ Easily Testable Code แต่ Worth Mentioning
Catch Errors เหล่านี้ทำให้ Debugging ยากขึ้น เพราะที่อื่นในโค้ดอาจ Raise Errors เดียวกัน อาจ Silence Serious Issues ใน App ที่ไม่ Necessarily Related กับที่คุณ Rescue
ใช้ ActiveRecord's Default Rollback Error อย่างมีสติ
ActiveRecord Provide Particular Error Class ที่คุณใช้ภายใน Transaction เพื่อ Silent Rollback คุณ Roll Back Transaction โดย Raise Error ActiveRecord::Rollback แต Error ไม่ Raise ภายนอกเหมือน Errors อื่น ให้ระลึกพฤติกรรมนี้และใช้อย่างมีสติ
3. รู้เมื่อไหร่ควรหลีกเลี่ยง Transactions ใน Rails
เหมือนทุกอย่าง คุณไม่ควร Overuse Transactions ในโค้ด ตัวอย่าง Common Mistake คือ Wrap Only One Query ใน Transaction ไม่ Make Sense เพราะถ้า Query ไม่ Succeed ไม่มีอะไร Roll Back
Common Mistake อีกอย่างคือ Wrap Code ที่ Unrelated กับ Database Call ใน Transaction ควรหลีกเลี่ยง Approach นี้ เพราะ Transaction จะ Hold Connection จนกว่า Code ภายใน Block Execute จำกัด Code ภายใน Block ให้ Call Only Database ถ้า Possible
4. เข้าใจ Disadvantages ของ Transactions
Transactions ช่วย Maintain Data Integrity ภายใน Database แต่คุณควร Aware Disadvantages ด้วย เช่น Queries ที่ Wrap ใน Transaction Block ใช้ DB Resources มากกว่า Single Queries
Drawback อีกอย่างคือมันทำให้ Code Complex มากขึ้น Transactions ทำ Code Less Readable เมื่อใช้ผิด
5. ใช้ Transaction Block ใน Context ที่ถูกต้อง
คุณใช้ Transaction Method ได้เมื่อ Class Inherit จาก ActiveRecord Class นี่ไม่ได้หมายความว่า Version ที่คุณใช้ไม่ Matter แม้อาจไม่ Matter จาก Functional Perspective แต Matter ใน Term ของ Readable Code
3 Common Versions ใช้ Transaction Method:
เมื่อใช้หลาย Models และ Mix Instance Method Invocations กับ Classes ภายใน Block ควรใช้ ActiveRecord::Base.transaction:
ถ้า Deal กับ Code ที่ส่วนใหญ่เป็นของ Model ใด Model ให้ Invoke Transaction Method บน Class:
ตอน Operate บน Model Instance สมเหตุสมผลที่จะ Invoke Transaction Method บน Instance Level:
แน่นอน Rules นี้ไม่ใช่ Official แค่ Suggestions ทำ Code Readable มากขึ้น
Next Steps: Review Transactions ใน Ruby on Rails Project ของคุณ
หวังว่าคุณพบ Tips เหล่านี้สำหรับ Transactions ใน Ruby on Rails มีประโยชน์
เรา Cover ความสำคัญของการ Design Rails Transactions ให้ถูกต้องเพื่อ Improve Data Integrity และ Ensure Processes Perform โดยไม่มี Surprising Side Effects
แต Error Handling Policy ที่ Proper ไม่ได้ Beneficial แค่ตอนใช้ Transactions — จะ Improve Whole Codebase ด้วย จดจำไว้ครั้งหน้าที่คุณคาดว่า Code จะ Throw Errors บ้าง
ตอนนี้เป็นเวลาดี Review Transactions ใน Ruby on Rails Project Design เพื่อหลีกเลี่ยง Errors Design สำหรับ Efficient และ Reliable Communication กับ Database ทำให้ App Stable มากขึ้น
Happy Coding!
P.S. หากต้องการอ่านบทความ Ruby Magic ทันทีที่เผยแพร่ สมัคร Newsletter Ruby Magic ของเราและจะไม่พลาดบทความเด็ดๆ ไป!
Paweł Dąbrowski
ผู้เขียน אורח Paweł เป็น Open-source Fan และ Growth Seeker ประมาณสิบปี Experience เขียนให้ทั้ง Man และ Computers เขา Connect Dots สร้าง High-quality Software และ Build Valuable Relations กับ People และ Businesses
บทความทั้งหมดโดย Paweł Dąbrowski