![](/img/trans.png)
[英]JDBC query does not see session.flush modifications on the same transaction
[英]Does a Hibernate transaction rollback delete “session.flush()”ed entities?
我對transaction.rollback
感到困惑。 這是示例偽代碼:
transaction = session.beginTransaction()
EntityA a = new EntityA();
session.save(a);
session.flush();
transaction.rollback();
這段代碼有效時會發生什么? 我是否在數據庫中擁有該實體?
簡答:不,你不會在數據庫中擁有實體。
更長的答案:hibernate足夠智能,不會向DB發送插入/更新,直到它知道事務是否將被提交或回滾(雖然這種行為可以通過設置不同的FlushMode來改變),在你的情況下通過調用flush您強制將SQL發送到數據庫,但仍然有數據庫事務來保護您,當您調用回滾時,數據庫事務將回滾,刪除在其自身內執行的更改,因此實際上不會保存任何內容。 請注意,根據您配置的事務隔離級別,其他事務可能會以某種方式查看您在保存和回滾之間保存的EntityA。 另請注意,當您嘗試從DB讀取時會自動調用flush,在99%的情況下,不需要顯式調用它。 我想到的一個例外是使用自動回滾測試進行單元測試時。
當你調用session.save(a)
Hibernate基本上會記住會話中的某個地方必須保存這個對象。 它可以決定是否要立即,稍后或提交時發出INSERT INTO...
這是性能改進,允許Hibernate批量插入或在事務回滾時避免它們。
當你調用session.flush()
,Hibernate被迫對數據庫發出INSERT INTO...
實體存儲在數據庫中,但尚未提交。 根據事務隔離級別,其他正在運行的事務將不會看到它。 但現在數據庫知道了記錄。
當您調用transaction.rollback()
,Hibernate回滾數據庫事務。 數據庫處理回滾,從而刪除新創建的對象。
現在考慮沒有flush()
的場景。 首先,你永遠不會觸摸數據庫,因此性能更好,回滾基本上是無操作。 另一方面,如果事務隔離級別為READ UNCOMMITTED
,則其他事務甚至可以在提交/回滾之前查看插入的記錄。 如果沒有flush()
這將不會發生,除非Hibernate沒有決定隱式地flush()
。
我認為你對flush
和commit
感到困惑。
flush()
使狀態與數據庫同步,但它沒有進行提交。 事務仍然可以看到狀態,因此您可以調用rollback進行回滾。
所以你的問題的答案是:不,你沒有數據庫中的實體(a)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.