10分鐘解決Hibernate的事務管理,Hibernate當中要設置事務的隔離級別

一、事務

1、什麼是事務:

事務:事物指的是邏輯上的一組操作,組成這一組操作的邏輯單元要麼全成功,要麼全失敗

2、事務的特性:

(1)原子性:代表事務不可分割。
(2)一致性:代表事務執行的前後,數據的完整性要保證一直。
(3)隔離性:代表的是一個事務執行的過程當中,不應該受到其他事務的干擾。
(4)持久性:代表一個事務執行完成後數據就持久到數據庫當中(提交或回滾)。

3、如果我們不考慮事務的隔離性,就會引發一些安全性的問題

(一)讀的問題
(1)髒讀:一個事務讀到另外一個事務未提交的數據
(2)不可重複讀:一個事務讀到了另一個事務已經提交的update的數據,導致在前一個事務多次查詢結果不一致
(3)虛度/幻讀:一個事務讀到另外一個事務已經提交的但是insert的數據,導致在前一個事務當中多次查詢的結果不一致
(二)寫的問題
(1)引發兩類丟失更新

4、讀問題的解決

(一)設置事務的隔離級別
1、Read uncommitted:未提交讀–以上的讀問題都會發生
2、Read commited:解決髒讀,但是不可重複讀和虛讀有可能發生(Oracle默認隔離級別)
3、Repeatable read:解決髒讀和不可重複讀,但是虛讀是有可能發生的(MySQL默認隔離級別)

4、Serializable:解決所有的讀問題(不能有事物的併發)(安全性高效率低)

二、Hibernate當中要設置事務的隔離級別

在這裏插入圖片描述
核心配置文件hibernate.cfg.xml當中配置對應的屬性
4是mysql的默認隔離級別
8是Oracle的默認隔離級別
在這裏插入圖片描述

三、Service層事務

1、Hibernate如何解決Service的事務管理

在這裏插入圖片描述

2、使用getCurrentSession獲取當前線程的session對象

(1)改寫工具類

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/* Hibernate的工具類*/
public class HibernateUtils {
	public static final Configuration cfg;
	public static final SessionFactory sf;
	static {
		cfg = new Configuration().configure();
		sf = cfg.buildSessionFactory();
	}
	public static Session openSession() {
		return sf.openSession();
	}
	public static Session getCurrentSession() {
		return sf.getCurrentSession();
	}
}
<!-- 設置事務隔離級別 -->
<property name="hibernate.connection.isolaction">4</property> 

(2)配置完成(hibernate的核心配置文件當中)
在這裏插入圖片描述

<!-- 配置當前線程來綁定的session -->
<property name="hibernate.current_session_context_class">thread</property>

getCurrentSession獲取當前線程的session對象,創建session對象之後不需要調用close方法,在線程結束的時候會自動將session關閉
(3)測試類

package com.itzheng.hibernate.demo01;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
 * 測試當前線程綁定的Session
 */
public class HibernateDemo04 {
	@Test
	public void demo01() {
		//會按照配置的好的事務處理方式去存儲數據
		Session session = HibernateUtils.getCurrentSession();//保證每一個對象在調用該方法的時候都使用的是同一個session
		Transaction transaction = session.beginTransaction();
		Customer customer = new Customer();
		customer.setCust_name("王西");
		session.save(customer);
		transaction.commit();
		//session.close();不需要二次關閉session。因爲在當前線程結束的時候就會關閉session對象,也就緩存
	}
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章