Field Summary |
static int |
TRANSACTION_NONE A constant indicating that transactions are not supported. |
static int |
TRANSACTION_READ_COMMITTED A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur. |
static int |
TRANSACTION_READ_UNCOMMITTED A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur. |
static int |
TRANSACTION_REPEATABLE_READ A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur. |
static int |
TRANSACTION_SERIALIZABLE A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented. |
事務級別越高,效率越低。
一般使用read-commited事務隔離級別,如果在程序中沒有指定事務隔離級別,則使用數(shù)據(jù)庫系統(tǒng)默認的級別。
Hibernate事務隔離級別:
隔離級別
|
臟讀 (Dirty Read)
|
不可重復讀(NonRepeatable Read)
|
幻讀 (Phantom Read)
|
讀操作未提交 (Read uncommitted)
|
可能
|
可能
|
可能
|
讀操作已提交 (Read commited)
|
不可能
|
可能
|
可能
|
可重復讀 (Repeatable read)
|
不可能
|
不可能
|
可能
|
可串行化 (Serializable)
|
不可能
|
不可能
|
不可能
|
設置隔離級別:
<property name=”hibernate.connection.isolation”>4</property> //可填1,2,4(不可重復讀),8
在以下的情況下,Hibernate會調(diào)用flush():
(1) 事務提交時,如果flush模式不為FlushMode.NEVER, commit()將調(diào)用flush().
(2) 在某些查詢語句之前(此查詢語句已經(jīng)改變了數(shù)據(jù)庫狀態(tài),所以需要調(diào)用flush()以同步數(shù)據(jù),使查出來的數(shù)據(jù)是經(jīng)過更改的)
(3) 當程序強制調(diào)用session.flush時。
在一個事務中調(diào)用一個select 查詢,如果此查詢之前已經(jīng)有某個update語句做了數(shù)據(jù)修改(注意此update語句并沒有真正執(zhí)行),則首先會調(diào)用flush(),使update對數(shù)據(jù)庫操作成功,接著才返回查詢數(shù)據(jù)。
FlushMode有以下幾種:
(1) FlushMode.AUTO: 數(shù)據(jù)有更改,則在查詢前更新此改動,以保證數(shù)據(jù)同步.
(2) FlushMode.COMMIT: 在事務結束之前刷新session
(3) FlushMode.NEVER: 僅在明確調(diào)用flush()時才對數(shù)據(jù)庫進行同步.
在Hibernate中使用JDBC事務:
Hibernate.transaction.factory_class=net.sf.hibernate.transaction.JDBCTransactionFactory
使用JTA 事務:
在一個具有多個數(shù)據(jù)庫的系統(tǒng)中,可能一個程序?qū){(diào)用幾個數(shù)據(jù)庫中的數(shù)據(jù),需要一種分布式事務,或者準備用JTA來管理跨Session的長事務,那么就需要使用JTATransaction.
Hibernate中對數(shù)據(jù)的鎖定:
如果要在事務中使用悲觀鎖,則可以像下面這樣寫:
Transaction tx=session.beginTransaction();
//取得持久化User對象,并使用LockMode.UPGRADE模式鎖定對象
User user=(User)session.get(User.class,LockMode.UPGRADE);
user.setName(“newName”); //更改對象屬性,注意并不需要使用session.save(user)
tx.commit();
這樣的話,Hibernate會使用select …… for update 語句載入User類,并且鎖住了這個對象在數(shù)據(jù)庫中的列,直到事務完成(commit()以后)。
Hibernate 可以利用Query或者Criteria的setLockMode()方法來設定要鎖定的表或列(Row)及其鎖定模式。可設定的模式有兩個:
(1) LockMod.UPGRADE
(2) LockMode.UPDGRADE_NOWAIT: