1. 程式人生 > >Hibernate 樂觀鎖和悲觀鎖處理事物併發問題

Hibernate 樂觀鎖和悲觀鎖處理事物併發問題

一、5類事物併發問題

二、事物的隔離級別

三、處理第一類丟失更新和第二類丟失更新--使用鎖機制

資料庫的鎖機制:
在MYSQL中 ,為了避免第二類丟失更新出現,提供了悲觀鎖的機制;
SELECT XXX FROM XXX    FOR UPDATE;

SELECT FOR UPDATE就是在資料上新增一個共享鎖的東西;
1,共享鎖允許其他普通的SELECT語句執行;
2,共享鎖排斥其他的SELECT  FOR UPDATE;
3,共享鎖排斥INSERT DELETE等DML;

在hibernate中使用悲觀鎖:
1,session1.createQuery("").setLockOptions(LockOptions.UPGRADE);
2,Account a=(Account)session1.get(Account.class,1L,LockOptions.UPGRADE);
3,Account a=(Account)session1.load(Account.class,1L,LockOptions.UPGRADE);

注意,
使用悲觀鎖會在一定情況下降低系統的併發效能;
如果系統對資料安全的要求非常高,請使用悲觀鎖;


樂觀鎖:
在hibernate中使用樂觀鎖:
1,在物件中新增一個private int version屬性,最好把setter/getter設定為private;
2,在對映檔案中新增:

四、例子

@Setter
@Getter
public class Account implements Serializable {

    private Long  id;
    private int vesion;
    private Double  balance;


}

配置檔案 

<hibernate-mapping  package="com.shenzhenair.day03.Transactions" >
	<class name="Account">
		<id name="id"  >
			<generator class="native"/>
		</id>
		<property name="vesion" />
		<property name="balance" />

	</class>


</hibernate-mapping>

 測試用例:

 @Test
    public void testTransaction(){
        Session session1 = HibernateUtils.openSession();
        session1.beginTransaction();
        Session session2 = HibernateUtils.openSession();
        session2.beginTransaction();

        Account a = (Account) session1.get(Account.class,1L);
        Account b = (Account) session2.get(Account.class,1L);

        a.setBalance(a.getBalance() - 5000);
        b.setBalance(b.getBalance() + 5000);

        try {
            session2.getTransaction().commit();
            session1.getTransaction().commit();
        } catch (HibernateException e) {
            e.printStackTrace();
            System.out.println("請稍後再進行操作!");
        }

        session2.close();
        session1.close();

    }