資料庫事務與併發 Hibernate

2021-09-30 03:36:39 字數 4834 閱讀 6404

資料庫事務與併發(hibernate)

資料庫事務中的基本概念

資料庫事務是指,由乙個或多個sql語句組成的工作單元,這個工作單元中的sql語句相互依賴,如果有乙個sql語句失敗,那麼整個操作都要撤銷。在併發環境中,當多個事務同時訪問同一資源時,可能會造成併發問題,此時可以使用資料庫系統的事務隔離級別來避免各類併發問題。此外,在應用程式中還可以使用悲觀鎖和樂觀鎖來解決丟失更新的併發問題。

資料庫事務必須具備acid的特徵(atomic原子性,consistency一致性,isolation隔離性,durability永續性)

原子性,指整個資料庫事務是不可分割的單元。只有所有的語句執行成功,才算成功。

一致性,指資料庫事務不能破壞關係資料的完整性以及業務邏輯上的一致性。

隔離性,指在併發環境中,當不同的事務同時操作相同的資料時,每個事務都有各自的完整資料空間。

永續性,指的是只要事務成功結束,對資料庫做的更新要永久儲存下來.

transaction和session的關係,應該注意以下幾點

transaction的rollback()和session的close()方法都會丟擲hibernateexception

不論事務是否成功,最後都應該關閉session。

即使事務中只包含唯讀操作,也應該在事務成功執行之後提交事務,並且在事務執行失敗時撤銷事務,因為在提交或撤銷事務時,資料庫系統會釋放占用的資源。

多個事務同時執行時的併發問題

第一類丟失更新,撤銷乙個事務時,把其他事務已提交的更新資料覆蓋了。

髒讀,乙個事務讀到另乙個事務未提交的更新資料。

虛讀,乙個事務讀到另乙個事務已提交的新插入的資料。

不可重複讀,乙個事務讀到另乙個事務已提交的更新資料。

第二類更新,乙個事務覆蓋另一事務已提交的更新資料。

資料庫系統鎖的基本原理

按照鎖定的資源的粒度,鎖可以分為以下型別

資料庫級鎖: 鎖定整個資料庫

表級鎖: 鎖定一張表

區域級鎖: 鎖定資料庫的特定區域

頁面級鎖: 鎖定資料庫的特定頁面

見面級鎖: 鎖定資料庫的特定頁面

鍵值級鎖: 鎖定資料庫表中帶有索引的一行資料。

行級鎖: 鎖定資料庫表中的但行資料(即一條記錄)

按照封鎖的程度,鎖可以分為: 共享鎖,獨佔鎖,更新鎖

共享鎖, 共享鎖用於讀資料操作,它是非獨佔的,允許其他事務同時讀取其鎖定的資源,但不允許其他事務更新資料。共享鎖的特徵:

加鎖條件:當乙個事務執行select操作時,資料庫系統就會為其分配一把共享鎖,來鎖定查詢資料。

解鎖條件:在預設情況下,資料讀取完畢,共享鎖就解除了。

與其他鎖的相容性:如果資料資源上放置了共享鎖,還能再放置共享鎖和更新鎖。

併發效能:具有良好的併發效能,當多個事務讀相同的資料時,每個事務都會獲得共享鎖,因此可以同時讀鎖定的資料。

獨佔鎖,也叫排它鎖,適用於修改資料的場合。它鎖定的資源,其他事務不能讀取也不能更新。獨佔鎖具有以下特徵:

加鎖的條件:當乙個事務執行insert、update、或delete語句時,資料庫就會為sql所操作的資料使用獨佔鎖。如果資料上有其他鎖,那麼就能放置獨佔鎖.

解鎖條件:到事務結束時才能被解除

與其他鎖的相容性:獨佔鎖不能和其他鎖相容。通用如果資源上有其他鎖,那麼也不能放置獨佔鎖。

併發效能:效能較差,只允許有乙個事務訪問鎖定的資料,如果其他事務也需要訪問該資料,就必須等待,直到前乙個事務結束,解除了獨佔鎖,其他事務才有機會訪問資源。

更新鎖,在更新操作的初始化階段用來鎖定可能要被修改的資源,這可以避免使用共享鎖造成死鎖的現象。更新具有以下特徵:

加鎖的條件:當乙個事務執行update語句時,資料庫系統會先為事務分配一把更新鎖。

解鎖條件:讀取資料完畢,執行更新操作時,會把更新鎖公升級為獨佔鎖。

與其他鎖的相容性:更新鎖與共享鎖是相容的。也就是說,乙個資源可以同時放置更新鎖和共享鎖,但是最多只能放置一把更新鎖。

併發效能:允許多個事務同時訪問資源。但不允許修改。

死鎖及其防止方法

合理安排表的訪問順序

使用短事務。將大事務分割為多個小事務執行。應該在處理事務之前就準備好使用者必須提供的資料。

如果對資料的一致性要求不高,可以允許髒度。

如果可能,錯開多個事務訪問相同資料資源的時間,以防止鎖衝突。

使用盡可能低的事務級別。

資料庫的隔離級別

儘管資料庫系統允許使用者在事務中顯示的為資料資源加鎖,但是首先應該考慮讓資料庫系統自動管理鎖,它會分析事務中的sql語句,然後自動為sql語句所操作的資料資源加上合適的鎖,而且在鎖的數目太多時,資料庫系統會自動的進行鎖公升級,以提供系統效能。

資料庫系統提供了四種事務隔離級別供使用者選擇:

serializable,序列化。

乙個事務在執行過程中完全看不到事務對資料庫所做的更新。當兩個事務同時運算元據庫中的資料時,如果第乙個事務已經在訪問該資料,那麼第二個事務只能停下來等待。

repeatable read:可重複讀

乙個事務在執行過程中可以看到其他事務已經提交的新插入的資料。但是不能看到其他事務對已有資料做的跟新。

read commited:讀已提交資料

乙個事務在執行過程中可以看到其他事務已經提交的新插入的資料。可以看到其他對已有資料進行的更新。

read uncommited:讀取未提交

乙個事務可以看到,其他事務沒有提交新插入的資料。而且更新操作的記錄也能看到。

//: 在hibernate.cfg.xml中配置

hibernate.connection.isolation=2

在應用程式中才用悲觀鎖和樂觀鎖

悲觀鎖與樂觀鎖的概念

悲觀鎖,在應用程式中顯示的為資料資源加鎖。可以防止丟失更新和不可重複讀問題。但是會影響效能。

樂觀鎖,假設當前的事務操作的資料,不會有其他事務同時訪問該資料資源,完全依靠資料庫系統自動管理鎖。因此可能會出現併發問題。

利用資料庫系統的獨佔鎖來實現悲觀鎖

悲觀鎖的兩種實現方式

應用中顯示的指定採用資料庫系統的獨佔鎖來鎖定資料資源。

在資料庫表中增加乙個表明記錄狀態的lock欄位,當它取值為y時,表示該i記錄已被某個事務鎖定。如果為n,表示該條資料為空閒狀態。

在hibernate中,當通過session的get()和load()方式來載入乙個物件時,可以採用以下方式使用悲觀鎖:

customer cus = (customer)session.get(customer.class, "c001", lockmode.upgrade); //: final org.hibernate.lockmode

lockmode類表示的幾種鎖定模式

鎖定模式 描述

lockmode.none 如果在hibernate快取中存在customer物件,就直接返回該引用。否則通過select載入。預設值

lockmode.read 不管快取中是否有,都使用select載入資料。如果對映檔案設定了版本元素,就執行版本檢查,比較快取中的與取到的是否版本一致。

lockmode.upgrade 不管快取中是否有,都使用select載入資料。就執行版本檢查,比較快取中的與取到的是否版本一致。如果資料庫系統支援悲觀鎖,那麼執行select…for update, 否則執行簡單的select

lockmode.upgrade_nowait 會執行lockmode.upgrade和它一樣的功能。若果執行的select不能立即獲得悲觀鎖,那麼就會丟擲異常

lockmode.write 當hibernate儲存或更新物件時,會自動使用這種鎖定模式。這種鎖定模式只在hibernate內部使用,所以在應用中不應該使用它

利用hibernate的版本控制來實現樂觀鎖

create table accounts (

id bigint primary key,

name varchar(15),

balance numeric(10,2),

last_updated_time timestamp,

version int

) 在hbm中配置版本控制

//: 在元素必須跟在元素的後面

//: 使用該元素也可以實現版本控制

對游離物件進行版本檢查

session session1 = ....;

trans1 = session1.begintransaction();

account a = (account)session1.get(account.class, new long(1));

trans1.commit();

session1.close();

a.setbalance(a.getbalance()-100);

session session2 = ...;

trans2 = session2.begintransaction();

session2.lock(a, lockmode.read);

trans2.commit();

session2.close();

lock() 方法和update()方法之間的區別

lock()方法在lockmode.read模式下,立即進行版本控制。而update()方法不會立即執行版本檢查,只有當session清理快取時,真正執行update時才進行版本檢查

lock()在預設的lockmode中不會執行update語句。而update()會計畫執行乙個update語句,如果資料庫中沒對應的記錄那麼會丟擲異常。

實現樂觀鎖的其他方式

//: optimistic-lock=all/dirty 時必須設定dynamic-update為true

資料庫事務與併發

資料庫事務必須具備acid特徵 1 原子性 指整個資料事務是不可分割的工作單元。只有事務中所有操作執行成功,才算整個事務成功 事務中任何乙個sql語句執行失敗,那麼已經執行成功的sql語句也必須撤銷,資料庫狀態應該退回到執行事務前的狀態。2 一致性 指資料庫事務不能破壞關係資料的完整性以及業務邏輯上...

資料庫事務與併發 Hibernate

資料庫事務中的基本概念 資料庫事務是指,由乙個或多個sql語句組成的工作單元,這個工作單元中的sql語句相互依賴,如果有乙個sql語句失敗,那麼整個操作都要撤銷。在併發環境中,當多個事務同時訪問同一資源時,可能會造成併發問題,此時可以使用資料庫系統的事務隔離級別來避免各類併發問題。此外,在應用程式中...

資料庫併發事務

比如有乙個方法a,在a的內部有兩次同樣的select查詢,但是在兩次select之間方法b對資料庫進行了修改,那麼查詢到的a兩次查詢到的內容是否一致呢,這其實就是資料庫的 不可重複讀 幻讀 問題 這裡用spring hibernate mysql實驗,如果方法a不在事務環境下執行,那麼查詢到的兩次結...