Hibernate上路_19-事務的丟失更新

事務的併發問題:髒讀、不可重複讀、幻讀。
    髒讀:一個事務讀取另外一個事務未提交的數據。
    不可重複讀:在一個事務中,讀取到另外一個事務已經提交update數據,形成兩次讀取不同。
    幻讀:在一個事務中,讀取到另外一個事務已經提交insert數據,形成讀取記錄條數不同。
    丟失更新:兩個事務同時修改目標數據,後提交的事務,會覆蓋以前提交的數據。 java

鑑於併發訪問出現的以上問題,數據庫提供了事務隔離級別:
    1. READ_UNCOMMITED:會發生以上全部問題
    2. READ_COMMITTED:阻止髒讀的發生,會發生不可重複讀和幻讀(Oracle 默認級別)
    3. REPEATABLE_READ:阻止髒讀和不可重複讀發生,會發生幻讀(MySQL 默認級別)
    4. SERIALIZABLE:不會發生併發問題,串行初始化(性能很是差,也不會使用)

mysql

1.MySql事務操做:

1start transaction:開始事務
2commit:提交事務

sql

2.修改MySql事務隔離級別:

<hibernate-configuration>
	<session-factory>
		<!-- 修改事務隔離級別 -->
		<property name="hibernate.connection.isolation">2</property>

隔離級別對應數值:
    read uncommitted isolation --- 1
    read committed isolation ------ 2
    repeatable read isolation ------ 4
    serializable isolation ----------- 8  數據庫

丟失更新問題解決:
    悲觀鎖和樂觀鎖。 session

2.悲觀鎖:

假設丟失更新發生機率很大,底層原理使用數據庫內部鎖的機制。 併發

    1Mysql數據庫內部提供讀鎖(共享鎖)、寫鎖(排它鎖 );
    2)一張數據表容許添加多個讀鎖;
    3)一張數據表只能添加一個寫鎖,其與其餘鎖互斥。添加了寫鎖則不能再添加讀鎖;
    4)默認狀況下,在修改記錄時,會自動添加寫鎖;
    5)在執行查詢時,也能夠爲數據添加共享鎖和排它鎖 
        select * from customer lock in share mode; 添加共享鎖 
        select * from customer for update; 添加排它鎖 
    6)悲觀鎖使用的便是排它鎖。第1個修改執行select * from customer for update,第個操做(包括查詢)須要等待
    session提供.get(Class class, Serializable id, LockMode lockMode); 
oracle

//類型,OID,鎖
PojoUser user = (PojoUser) session.get(PojoUser.class, 1, LockMode.UPGRADE);
//更新操做
user.setName("XXxxx");
mysql 對應 LockMode UPGRADE
oracle  對應 LockMode UPGRADE_NOWAIT


3.樂觀鎖:

假設丟失更新發生機率不高,底層原理爲數據添加版本號,由程序來維護版本。 app

1)在POJO中添加Integer version字段:

2)在POJO.hbm.xml中添加版本字段:

3)加斷點在debug模式測試:

提交的版本號和數據庫中版本不一樣則報錯: dom

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [cn.cvu.hibernate.domain.PojoUser#3] 

- end
   性能

相關文章
相關標籤/搜索