[英]What will happen if we begin transaction in hibernate but do not commit it?
如果我們在hibernate中開始事務,然后做一些事務但不提交它會發生什么? 它會拯救它還是會立即回滾?
謝謝Chetan
查看以下代碼,該代碼使用事務邊界訪問數據庫而不使用commit:
Session session = sessionFactory.openSession();
session.beginTransaction();
session.get(Item.class, 123l);
session.close();
默認情況下,在具有JDBC配置的Java SE環境中,如果執行此代碼段,則會發生以下情況:
SELECT在此JDBC事務中執行。 會話關閉,連接返回到池並由Hibernate釋放 - Hibernate在JDBC Connection上調用close()。
未提交的交易會發生什么?
這個問題的答案是,“它取決於!”在連接上調用close()時,JDBC規范沒有說明掛起事務的任何內容。 發生的情況取決於供應商如何實施規范。 例如,使用Oracle JDBC驅動程序,對close()的調用將提交事務! 當JDBC Connection對象關閉並且資源返回到池時,大多數其他JDBC供應商采用理智的路由並回滾任何掛起的事務。
顯然,對於您執行的SELECT,這不會是一個問題,但請看這個變化:
Session session = getSessionFactory().openSession();
session.beginTransaction();
Long generatedId = session.save(item);
session.close();
此代碼生成一個INSERT語句,在從未提交或回滾的事務中執行。 在Oracle上,這段代碼永久地插入數據; 在其他數據庫中,它可能不會。 (這種情況稍微復雜一點:只有在標識符生成器需要它時才執行INSERT。例如,可以從沒有INSERT的序列中獲取標識符值。然后將持久化實體排隊,直到刷新時插入 - 從不在這段代碼中發生。身份策略需要立即INSERT才能生成值。)
它依賴於hibernate-config和連接池配置。
當嘗試用打開的事務關閉一個會話hibernate默認情況下不會調用關閉連接代理(如果你想改變這個你需要定義 - hibernate.ejb.discard_pc_on_close是真的)
public void close() {
if ( !open ) {
throw new IllegalStateException( "EntityManager is closed" );
}
if ( !discardOnClose && isTransactionInProgress() ) {
現在,假設您定義了discard_pc_on_close,而不是在這種情況下,hibernate將在連接代理(連接池包裝連接)上調用close,所以現在我們依賴於連接池如何實現它。 您可以在:NewPooledConnection中看到c3p0實現。 您將看到它依賴於此標志 - FORCE_IGNORE_UNRESOLVED_TXNS(默認為false),因此默認情況下它將重置事務。
static void resetTxnState( Connection pCon,
boolean forceIgnoreUnresolvedTransactions,
boolean autoCommitOnClose,
boolean txnKnownResolved ) throws SQLException
{
if ( !forceIgnoreUnresolvedTransactions && !pCon.getAutoCommit() )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.