標籤:儲存 安全 date save thread htm question 方式 update
摘自百度知道:http://zhidao.baidu.com/question/63663640.html
問:先建立一個Student,然後調用session.save方法,然後再調用evict方法把Student對象清除出緩衝,再提交事務, 可是會報錯:Exception in thread "main" org.hibernate.AssertionFailure: possible nonthreadsafe access to session 但是如果我用的不是evict方法,而是clear方法用來清除緩衝的話,程式沒有錯。 答:session.evict(obj),會把指定的緩衝對象進行清除session.clear(),把緩衝區內的全部對象清除,但不包括操作中的對象所以,hibernate執行的順序如下,(1)產生一個事務的對象,並標記當前的Session處於事務狀態(註:此時並未啟動資料庫級事務)。 (2)應用使用s.save儲存對象,這個時候Session將這個對象放入entityEntries,用來標記對象已經和當前的會話建立了關聯,由於應用對對象做了儲存的操作,Session還要在insertions中登記應用的這個插入行為(行為包括:對象引用、對象id、Session、持久化處理類)。(3)s.evict將對象從s會話中拆離,這時s會從entityEntries中將這個對象移出。(4)事務提交,需要將所有緩衝flush入資料庫,Session啟動一個事務,並按照insert,update,……,delete的順序提交所有之前登記的操作(注意:所有insert執行完畢後才會執行update,這裡的特殊處理也可能會將你的程式搞得一團糟,如需要控制操作的執行順序,要善於使用flush),現在對象不在entityEntries中,但在執行insert的行為時只需要訪問insertions就足夠了,所以此時不會有任何的異常。異常出現在插入後通知Session該對象已經插入完畢這個步驟上,這個步驟中需要將entityEntries中對象的existsInDatabase標誌置為true,由於對象並不存在於entityEntries中,此時Hibernate就認為insertions和entityEntries可能因為安全執行緒的問題產生了不同步(也不知道Hibernate的開發人員是否考慮到例子中的處理方式,如果沒有的話,這也許算是一個bug吧),於是一個net.sf.hibernate.AssertionFailure就被拋出,程式終止一般錯誤的認為s.save會立即的執行,而將對象過早的與Session拆離,造成了Session的insertions和entityEntries中內容的不同步。所以我們在做此類操作時一定要清楚Hibernate什麼時候會將資料flush入資料庫,在未flush之前不要將已進行操作的對象從Session上拆離。解決辦法是在save之後,添加session.flush。
hibernate 的evict 和clear