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 代碼 |
---|---|
|
|
所以本機 Hibernate 事務只是對數據庫的本機 JDBC 調用。僅此而已。但 JTA 事務更有趣。但下次再談。
GO TO FULL VERSION