4.1 ข้อมูลเบื้องต้นเกี่ยวกับการทำธุรกรรมใน Hibernate

จากทั้งหมดข้างต้น ฉันต้องการเพิ่มข้อมูลเกี่ยวกับการทำธุรกรรม ดังที่คุณทราบแล้ว ธุรกรรมคือกลุ่มของการกระทำที่ต้องดำเนินการทั้งหมดพร้อมกันเท่านั้น หากการดำเนินการใดๆ ล้มเหลวหรือดำเนินการโดยมีข้อผิดพลาด การดำเนินการอื่นๆ ทั้งหมดจะต้องถูกยกเลิก

ไฮเบอร์เนตสามารถทำงานกับธุรกรรมสองประเภท:

  • เจดีบีซี
  • เจ.ที

ธุรกรรม 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 อย่างง่าย

Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the database
session.flush();
transaction.commit();
session.close();

Connection conn = jdbcContext.connection();
conn.setAutoCommit(false);
 
//here is your database code
conn.commit ()
conn.setAutoCommit(true);
conn.close();

ดังนั้นธุรกรรม Hibernate ดั้งเดิมจึงเป็นเพียงการเรียก JDBC ดั้งเดิมไปยังฐานข้อมูล ไม่มีอะไรมากไปและไม่มีอะไรน้อยไป แต่การทำธุรกรรม JTA นั้นน่าสนใจกว่า แต่เพิ่มเติมเกี่ยวกับเรื่องนั้นอีกครั้ง