เมื่อคุณเชื่อมต่อผ่าน PDO แล้ว ก่อนที่คุณจะเริ่มการสืบค้น คุณต้องเข้าใจก่อนว่า PDO จัดการธุรกรรมอย่างไร
ธุรกรรมรองรับลักษณะสำคัญสี่ประการ (ACID):
อะตอมมิกซิตี
ความสม่ำเสมอ
การแยกตัว
ความทนทาน
ในแง่ของคนทั่วไป การดำเนินการใดๆ ที่ทำภายในธุรกรรม แม้ว่าจะดำเนินการเป็นขั้นตอนก็ตาม จะรับประกันได้ว่าจะสามารถนำไปใช้กับฐานข้อมูลได้อย่างปลอดภัย และกระทำโดยปราศจากการแทรกแซงจากการเชื่อมต่ออื่นๆ
การดำเนินการธุรกรรมสามารถยกเลิกได้โดยอัตโนมัติตามคำขอ (สมมติว่ายังไม่ได้ดำเนินการ) ทำให้ง่ายต่อการจัดการข้อผิดพลาดในสคริปต์
โดยปกติแล้วธุรกรรมจะดำเนินการโดยการ "สะสม" ชุดการเปลี่ยนแปลงและทำให้มีประสิทธิภาพในเวลาเดียวกัน ข้อดีของการทำเช่นนี้คือสามารถปรับปรุงประสิทธิภาพของการเปลี่ยนแปลงเหล่านี้ได้อย่างมาก
กล่าวอีกนัยหนึ่ง ธุรกรรมสามารถทำให้สคริปต์เร็วขึ้นและมีประสิทธิภาพมากขึ้น (แม้ว่าธุรกรรมจะต้องใช้อย่างถูกต้องเพื่อรับผลประโยชน์ดังกล่าว)
น่าเสียดายที่ไม่ใช่ทุกฐานข้อมูลที่รองรับธุรกรรม ดังนั้น PDO จำเป็นต้องทำงานในโหมดที่เรียกว่า "ดำเนินการอัตโนมัติ" เมื่อเปิดการเชื่อมต่อครั้งแรก
โหมดส่งอัตโนมัติหมายความว่าการเรียกใช้แบบสอบถามแต่ละครั้งมีธุรกรรมโดยนัยของตัวเองหากฐานข้อมูลรองรับ หรือไม่ไม่มีเลยหากฐานข้อมูลไม่รองรับธุรกรรม
หากจำเป็นต้องมีธุรกรรม จะต้องเริ่มต้นด้วยเมธอด PDO::beginTransaction() หากไดรเวอร์พื้นฐานไม่รองรับธุรกรรม PDOException จะถูกส่งออกไป (นี่เป็นเงื่อนไขข้อผิดพลาดร้ายแรงโดยไม่คำนึงถึงการตั้งค่าการจัดการข้อผิดพลาด)
เมื่อธุรกรรมเริ่มต้นขึ้น ก็สามารถดำเนินการให้เสร็จสิ้นได้ด้วย PDO::commit() หรือ PDO::rollBack() ขึ้นอยู่กับว่าโค้ดในธุรกรรมทำงานได้สำเร็จหรือไม่
หมายเหตุ: PDO จะตรวจสอบว่ามีความสามารถในการทำธุรกรรมในระดับไดรเวอร์หรือไม่ หากเงื่อนไขรันไทม์บางประการหมายความว่าธุรกรรมไม่พร้อมใช้งาน และบริการฐานข้อมูลยอมรับคำขอเพื่อเริ่มธุรกรรม PDO::beginTransaction() จะยังคงส่งคืน TRUE โดยไม่มีข้อผิดพลาด ตัวอย่างที่ดีคือการพยายามใช้ธุรกรรมในตาราง MyISAM ในฐานข้อมูล MySQL
เมื่อสคริปต์สิ้นสุดลงหรือการเชื่อมต่อกำลังจะปิด หากมีธุรกรรมค้างชำระ PDO จะย้อนกลับธุรกรรมโดยอัตโนมัติ มาตรการความปลอดภัยนี้ช่วยหลีกเลี่ยงความไม่สอดคล้องกันหากสคริปต์ยุติโดยไม่คาดคิด - หากธุรกรรมไม่ได้ถูกกระทำอย่างชัดเจน จะถือว่ามีบางอย่างผิดพลาด ดังนั้นจึงดำเนินการย้อนกลับเพื่อรักษาข้อมูลให้ปลอดภัย
หมายเหตุ: การย้อนกลับอัตโนมัติอาจเกิดขึ้นหลังจากเริ่มธุรกรรมผ่าน PDO::beginTransaction() เท่านั้น หากคุณออกแบบสอบถามด้วยตนเองเพื่อเริ่มธุรกรรม PDO ไม่มีทางทราบและไม่สามารถย้อนกลับได้หากจำเป็น
ดำเนินการประมวลผลเป็นชุดในธุรกรรม:
ในตัวอย่างต่อไปนี้ สมมติว่าชุดของรายการถูกสร้างขึ้นสำหรับพนักงานใหม่และกำหนด ID เป็น 23 นอกจากการลงทะเบียนข้อมูลพื้นฐานของบุคคลแล้ว ยังจำเป็นต้องบันทึกเงินเดือนของเขาด้วย
การอัปเดตทั้งสองแยกจากกันเป็นเรื่องง่าย แต่โดยการรวมการอัปเดตทั้งสองไว้ในการเรียก PDO::beginTransaction() และ PDO::commit() คุณจะมั่นใจได้ว่าจะไม่มีใครเห็นการเปลี่ยนแปลงได้จนกว่าจะเสร็จสมบูรณ์
หากมีข้อผิดพลาดเกิดขึ้น catch block จะย้อนกลับการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นตั้งแต่เริ่มธุรกรรมและพิมพ์ข้อความแสดงข้อผิดพลาด
<?phptry { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO::ATTR_PERSISTENT => true)); echo "เชื่อมต่อn";} catch (ยกเว้น $e) { die("ไม่สามารถเชื่อมต่อ: " . $e->getMessage());} ลอง { $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->beginTransaction(); $dbh->exec("ใส่เข้าไปในค่าพนักงาน (id, first, Last) (23, 'Joe) ', 'Bloggs')"); $dbh->exec("insert into allowance (id, amount, changesate) ค่า (23, 50000, NOW())"); $dbh->commit(); } catch (ข้อยกเว้น $e) { $dbh->rollBack(); echo "Failed: " . $e->getMessage();}?>
คุณไม่ได้จำกัดอยู่เพียงการเปลี่ยนแปลงภายในธุรกรรม คุณยังสามารถออกคำถามที่ซับซ้อนเพื่อดึงข้อมูล และคุณสามารถใช้ข้อมูลนั้นเพื่อสร้างการเปลี่ยนแปลงและการสอบถามเพิ่มเติมได้ เมื่อธุรกรรมดำเนินอยู่ คุณสามารถรับประกันได้ว่าผู้อื่นจะไม่สามารถทำการเปลี่ยนแปลงได้ในขณะที่ อยู่ระหว่างดำเนินการ