交易

SQL & Hibernate
等級 16 , 課堂 3
開放

4.1 Hibernate 中的事務介紹

對於以上所有內容,我想添加有關交易的信息。如您所知,事務是一組必須一起執行的操作。如果任何操作失敗或執行出錯,則必須取消所有其他操作。

Hibernate 能夠處理兩種類型的事務:

  • JDBC
  • JTA

JDBC 事務實際上是數據庫事務。它與使用數據庫、JDBC 連接相關聯。並且他確保使用數據庫時的操作按應有的方式執行:要么全部執行,要么什麼都不執行。

JTA - 事務是應用程序級別的事務。它不綁定到任何數據庫。它的任務是確保執行某些操作:全部或不執行。

例如,您可以在單個 JTA 事務中將數據寫入多個不同的數據庫。然後如果發生錯誤,那麼 JTA 事務將不得不回滾所有數據庫中的更改。即使是那些在特定數據庫方面成功執行的。

4.2 Hibernate 事務接口

在 Hibernate 庫中,事務由 Transaction 接口表示,它可以有不同的實現。例如,在與 Spring 合作時,Spring 提供了自己的 JTA 事務機制。

該接口的方法有:

# 方法 描述
1個 開始() 開始新的交易
2個 犯罪() 結束事務,推送/提交所有更改
3個 回滾() 回滾當前事務
4個 設置超時(整數秒) 設置最大事務執行時間
5個 活躍() 檢查事務是否處於活動狀態
6個 被回滾() 檢查事務是否正常回滾
7 已提交() 檢查事務是否正常提交
8個 註冊同步() 註冊一個回調來控制事務

重要的!創建事務對象和啟動事務是兩件不同的事情。這裡可以類比Thread類。當您創建 Thread() 對象時,JVM 尚未啟動新線程。要啟動它,您需要調用 Thread 對象的 start() 方法。事務也是如此——它需要調用 begin() 方法。

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(). begin()這意味著 TransactionManger 必須首先記錄和之間的所有操作commit(),然後返回調用 時的所有內容rollback()

順便說一句,調用回滾方法不會出錯也不是事實。錯誤總是會發生。您只需要接受這個事實並為此做好準備。

4.3 事務管理器

從事務管理的角度來看,Hibernate 只是 JDBC 的輕量級對象包裝器。Hibernate 本身沒有事務處理特性。Hibernate Transaction 實際上是底層 JDBC 事務的包裝器(或 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);
    	...
    }
}

這是啟動事務的方法。然後看send方法:


public void commit() throws HibernateException {
    ...
    jdbcContext.connection().commit();
    ...
    jdbcContext.connection().setAutoCommit( true );
    ...
}

現在讓我們將此代碼替換為 Hibernate 示例代碼:

休眠 簡單的 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 事務更有趣。但下次再談。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION