4.1 ข้อมูลเบื้องต้นเกี่ยวกับการทำธุรกรรมใน Hibernate
จากทั้งหมดข้างต้น ฉันต้องการเพิ่มข้อมูลเกี่ยวกับการทำธุรกรรม ดังที่คุณทราบแล้ว ธุรกรรมคือกลุ่มของการกระทำที่ต้องดำเนินการทั้งหมดพร้อมกันเท่านั้น หากการดำเนินการใดๆ ล้มเหลวหรือดำเนินการโดยมีข้อผิดพลาด การดำเนินการอื่นๆ ทั้งหมดจะต้องถูกยกเลิก
![](https://cdn.codegym.cc/images/article/f5ab4cb5-18c2-42e5-83a4-9a4d93f30414/1024.jpeg)
ไฮเบอร์เนตสามารถทำงานกับธุรกรรมสองประเภท:
- เจดีบีซี
- เจ.ที
ธุรกรรม JDBC เป็นธุรกรรมฐานข้อมูล มันเชื่อมโยงกับการทำงานกับฐานข้อมูลกับการเชื่อมต่อ JDBC และเขาตรวจสอบให้แน่ใจว่าการดำเนินการเมื่อทำงานกับฐานข้อมูลนั้นเป็นไปตามที่ควรจะเป็น: ทั้งหมดหรือไม่มีเลย
JTA - ธุรกรรมเป็นธุรกรรมระดับแอปพลิเคชัน ไม่เชื่อมโยงกับฐานข้อมูลใด ๆ หน้าที่ของมันคือเพื่อให้แน่ใจว่ามีการดำเนินการบางอย่าง: ทั้งหมดหรือไม่มีเลย
ตัวอย่างเช่น คุณสามารถเขียนข้อมูลไปยังฐานข้อมูลต่างๆ ได้หลายฐานข้อมูลภายในธุรกรรม JTA เดียว จากนั้นหากเกิดข้อผิดพลาด ธุรกรรม JTA จะต้องย้อนกลับการเปลี่ยนแปลงในฐานข้อมูลทั้งหมด แม้แต่ผู้ที่ดำเนินการสำเร็จในแง่ของฐานข้อมูลเฉพาะ
4.2 อินเทอร์เฟซการทำธุรกรรมไฮเบอร์เนต
ในไลบรารี Hibernate ทรานแซกชันจะแสดงโดยอินเทอร์เฟซทรานแซกชัน ซึ่งสามารถมีการใช้งานที่แตกต่างกันได้ ตัวอย่างเช่น เมื่อทำงานกับ Spring สปริงจะมีกลไกธุรกรรม JTA ของตัวเอง
วิธีการของอินเทอร์เฟซนี้คือ:
# | วิธี | คำอธิบาย |
---|---|---|
1 | เริ่ม() | เริ่มธุรกรรมใหม่ |
2 | ให้สัญญา() | สิ้นสุดการทำธุรกรรม พุช/ยอมรับการเปลี่ยนแปลงทั้งหมด |
3 | ย้อนกลับ () | ย้อนกลับธุรกรรมปัจจุบัน |
4 | setTimeout (int วินาที) | ตั้งเวลาดำเนินการธุรกรรมสูงสุด |
5 | isActive() | ตรวจสอบว่ามีการทำธุรกรรมที่ใช้งานอยู่หรือไม่ |
6 | ถูกย้อนกลับ () | ตรวจสอบว่าธุรกรรมย้อนกลับตามปกติหรือไม่ |
7 | เป็นความมุ่งมั่น () | ตรวจสอบว่าการทำธุรกรรมได้กระทำตามปกติหรือไม่ |
8 | การลงทะเบียนซิงโครไนซ์ () | ลงทะเบียนการโทรกลับเพื่อควบคุมการทำธุรกรรม |
สำคัญ! การสร้างวัตถุธุรกรรมและการเริ่มต้นธุรกรรมเป็นสองสิ่งที่แตกต่างกัน คุณสามารถวาดความคล้ายคลึงกับคลาสเธรดได้ที่นี่ เมื่อคุณสร้างวัตถุ Thread() JVM จะยังไม่เริ่มเธรดใหม่ ในการเริ่มต้น คุณต้องเรียกใช้เมธอด start() บนวัตถุเธรด มันเหมือนกันกับการทำธุรกรรม - มันจำเป็นต้องเรียกเมธอด start()
ตัวอย่างของวิธีจัดการธุรกรรมใน Hibernate:
Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Long count = session.createQuery("select count(*) from Employee", Long.class).uniqueResult();
transaction.commit();
}
catch (Exception e) {
if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
transaction.rollback();
}
}
finally {
session.close();
sessionFactory.close();
}
เราเห็นสามสิ่งที่นี่:
ขั้นแรก การทำงานทั้งหมดกับฐานข้อมูลจะรวมอยู่ในธุรกรรมโดยวิธีการเรียกbegin()
และcommit()
ต้องดำเนินการทั้งหมดระหว่างการเรียกไปยังสองวิธีนี้: ทั้งหมดพร้อมกันหรือไม่ทำอะไรเลย
ประการที่สอง หากมีข้อผิดพลาดเกิดขึ้น เราจะพยายามย้อนกลับการทำธุรกรรม - rollback()
เรียก ซึ่งหมายความว่า TransactionManger จะต้องบันทึกการดำเนินการทั้งหมดที่อยู่ระหว่างและbegin()
ก่อนcommit()
จากนั้นจึงส่งคืนทุกอย่างตามเดิมหากเราเรียกใช้rollback()
และไม่ใช่ความจริงที่ว่าจะไม่มีข้อผิดพลาดเมื่อเรียกวิธีการย้อนกลับ ความผิดพลาดเกิดขึ้นได้เสมอ คุณเพียงแค่ต้องยอมรับข้อเท็จจริงนี้และเตรียมพร้อมสำหรับมัน
4.3 ผู้จัดการธุรกรรม
จากมุมมองของการจัดการธุรกรรม Hibernate เป็นเพียงตัวห่อหุ้มวัตถุขนาดเล็กสำหรับ JDBC ไฮเบอร์เนตเองไม่มีคุณสมบัติการประมวลผลธุรกรรม Hibernate Transaction เป็น wrapper สำหรับธุรกรรม JDBC พื้นฐาน (หรือ wrapper ธุรกรรม JTA) JDBCTransaction เป็นค่าเริ่มต้น ตัวอย่างจากไฟล์การตั้งค่า Hiberante:
hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory
มาดูรหัสของเราอีกครั้งโดยใช้ธุรกรรม:
Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the base
session.flush();
transaction.commit();
session.close();
ทีนี้มาดูรหัสคลาส JDBCTransaction:
public class JDBCTransaction implements Transaction {
public void begin() throws HibernateException {
...
if (toggleAutoCommit) jdbcContext.connection().setAutoCommit(false);
...
}
}
นี่คือวิธีการเริ่มต้นการทำธุรกรรม จากนั้นดูวิธีการส่ง:
public void commit() throws HibernateException {
...
jdbcContext.connection().commit();
...
jdbcContext.connection().setAutoCommit( true );
...
}
ตอนนี้ให้แทนรหัสนี้เป็นรหัสตัวอย่างไฮเบอร์เนต:
ไฮเบอร์เนต | รหัส JDBC อย่างง่าย |
---|---|
|
|
ดังนั้นธุรกรรม Hibernate ดั้งเดิมจึงเป็นเพียงการเรียก JDBC ดั้งเดิมไปยังฐานข้อมูล ไม่มีอะไรมากไปและไม่มีอะไรน้อยไป แต่การทำธุรกรรม JTA นั้นน่าสนใจกว่า แต่เพิ่มเติมเกี่ยวกับเรื่องนั้นอีกครั้ง