Hibernate does not lock objects in memory. Your application can expect the behavior as defined by the isolation level of your database transactions.
Note that thanks to the Session, which is also a transaction-scoped cache, Hibernate provides repeatable reads for lookup by identifier and entity queries (not reporting queries that return scalar values).
Hibernate 沒有提供在內存中對對象加鎖的功能,因此應用的事務隔離級別是完全由數據庫來提供的。
借助于session,Hibernate 提供了可重復讀的事務隔離級別,但是前提是只有使用identifier and entity queries的可以,使用標量查詢則不可以,其原因是hibernate的cache的對象需要是能夠被唯一識別的實體對象,標量查詢返回的結果是數組,不滿足該要求,無法在session級別進行事務的cache
在事務和并發性方面,hibernate不僅提供了基于版本的控制的自動樂觀鎖機制,同時還提供了API來實現悲觀鎖機制(通過SELECT FOR UPDATE 語法)
A SessionFactory is an expensive-to-create, threadsafe object intended to be shared by all application threads. It is created once, usually on application startup, from a Configuration instance.
A Session is an inexpensive, non-threadsafe object that should be used once, for a single request, a conversation, single unit of work, and then discarded. A Session will not obtain a JDBC Connection (or a Datasource) unless it is needed, hence consume no resources until used.
Database transactions are never optional, all communication with a database has to occur inside a transaction, no matter if you read or write data.
事務并不是可有可無的,所有的數據庫操作都是在事務環境下發生的,不管是read 操作還是write操作。這點一定要名明確,以前曾經誤解。
As explained, auto-commit behavior for reading data should be avoided, as many small transactions are unlikely to perform better than one clearly defined unit of work. The latter is also much more maintainable and extensible.
最好關閉自動提交功能,因為使用大量的短數據庫事務在性能上未必比一個清晰定義的unit work強,后者更加易于維護和擴展。(以前曾經誤解)
樂觀鎖的處理方式
Hibernate checks instance versions at flush time, throwing an exception if concurrent modification is detected.It's up to the developer to catch and handle this exception (common options are the opportunity for the user to merge changes or to restart the business conversation with non-stale data).
在flush的時候檢查version,如果發現更改會拋出異常,開發人員可以捕捉該異常,并決定如何處理(要么合并修改,要么放棄修改)
悲觀鎖的處理方式
悲觀鎖基本上是靠數據庫本身提供的機制來實現,通常只要為jdbc connection指定事務隔離的級別即可。The LockMode class defines the different lock levels that may be acquired by Hibernate.
悲觀鎖會在讀取數據之前獲取,因此能夠保證當前事務的數據就是最新數據。
hibernate的查詢分類:
1、標量查詢(Scalar queries):返回的記錄數組的集合
標量是與數組相對的概念,是一種由單一的值來表征的量。所謂標量查詢,就是直接使用原生sql語句的查詢,也即返回的是裸數據(只不過hibernate使用ResultSetMetaData將resultset中的每一條記錄放到一個數組Object[]中
)。
比如
List list = session.createSQLQuery("select * from t_area_person").list();
for (Object object : list) {
Object[] ob = (Object[]) object;
for (int i = 0; i < ob.length; i++)
System.out.print(" " +ob[i]);
System.out.println();
}
2、實體查詢(Entity queries):返回的是實體對象的集合
3、Load方法:lookup by identifier ,返回的是該identifier 對應的對象