久久久久久AV无码免费看大片,亚洲一区精品人人爽人人躁,国产成人片无码免费爱线观看,亚洲AV成人无码精品网站,为什么晚上搞的时候要盖被子

什么是事務(wù)及事務(wù)并發(fā)的可能問(wèn)題與其解決方案

時(shí)間:2020-09-25 22:11:31 類(lèi)型:數(shù)據(jù)庫(kù)
字號(hào):    

  我們?cè)趯?shí)際業(yè)務(wù)場(chǎng)景中,經(jīng)常會(huì)遇到數(shù)據(jù)頻繁修改讀取的問(wèn)題。在同一時(shí)刻,不同的業(yè)務(wù)邏輯對(duì)同一個(gè)表數(shù)據(jù)進(jìn)行修改,

  這種沖突很可能造成數(shù)據(jù)不可挽回的錯(cuò)亂,所以我們需要用事務(wù)來(lái)對(duì)數(shù)據(jù)進(jìn)行管理。

   事務(wù)的概念

  事務(wù)必須服從ACID原則。ACID指的是原子性(atomicity)、一致性(consistency)、隔離性(isolation)

  和持久性(durability)。通俗理解,事務(wù)其實(shí)就是一系列指令的集合。

  原子性:操作這些指令時(shí),要么全部執(zhí)行成功,要么全部不執(zhí)行。只要其中一個(gè)指令執(zhí)行失敗,

  所有的指令都執(zhí)行失敗,數(shù)據(jù)進(jìn)行回滾,回到執(zhí)行指令前的數(shù)據(jù)狀態(tài)。

  一致性:事務(wù)的執(zhí)行使數(shù)據(jù)從一個(gè)狀態(tài)轉(zhuǎn)換為另一個(gè)狀態(tài),但是對(duì)于整個(gè)數(shù)據(jù)的完整性保持穩(wěn)定。

  隔離性:在該事務(wù)執(zhí)行的過(guò)程中,無(wú)論發(fā)生的任何數(shù)據(jù)的改變都應(yīng)該只存在于該事務(wù)之中,

  對(duì)外界不存在任何影響。只有在事務(wù)確定正確提交之后,才會(huì)顯示該事務(wù)對(duì)數(shù)據(jù)的改變。

  其他事務(wù)才能獲取到這些改變后的數(shù)據(jù)。

  持久性:當(dāng)事務(wù)正確完成后,它對(duì)于數(shù)據(jù)的改變是永久性的。


一、多個(gè)事務(wù)并發(fā)時(shí)可能遇到的問(wèn)題

1. 第一類(lèi)丟失更新(lost update): 在完全未隔離事務(wù)的情況下,兩個(gè)事物更新同一條數(shù)據(jù)資源,某一事物異常終止,回滾造成第一個(gè)完成的更新也同時(shí)丟失。

2. 臟讀(dirty read):如果第二個(gè)事務(wù)查詢(xún)到第一個(gè)事務(wù)還未提交的更新數(shù)據(jù),形成臟讀。

3. 虛讀(phantom read):一個(gè)事務(wù)執(zhí)行兩次查詢(xún),第二次查詢(xún)比第一次多出或少一些數(shù)據(jù),造成兩次結(jié)果不一致。只是另一個(gè)事務(wù)在這兩次查詢(xún)中間插入或者刪除了數(shù)據(jù)造成的。

4. 不可重復(fù)讀(unrepeated read):一個(gè)事務(wù)兩次讀取同一行數(shù)據(jù),結(jié)果得到不同狀態(tài)結(jié)果,如中間正好另一個(gè)事務(wù)更新了該數(shù)據(jù),兩次結(jié)果相異,不可信任。

5. 第二類(lèi)丟失更新(second lost updates):是不可重復(fù)讀的特殊情況,如果兩個(gè)事務(wù)都讀取同一行,然后兩個(gè)都進(jìn)行寫(xiě)操作,并提交,第一個(gè)事務(wù)所做的改變就會(huì)丟失。

兩類(lèi)更新丟失的舉例:

時(shí)間取款事務(wù)A轉(zhuǎn)賬事務(wù)B
T1開(kāi)始事務(wù)
T2
開(kāi)始事務(wù)
T3讀余額為1000
T4取出100,余額改為900-
T5
讀余額為1000
T6
匯入100,余額改為1100
T7
提交事務(wù),余額定為1100
T8撤銷(xiāo)事務(wù),余額改回1000-
T9最終余額1000,更新丟失-

寫(xiě)操作沒(méi)加“持續(xù)-X鎖”,沒(méi)能阻止事務(wù)B寫(xiě),發(fā)生了回滾覆蓋。

時(shí)間轉(zhuǎn)賬事務(wù)A取款事務(wù)B
T1開(kāi)始事務(wù)
T2
開(kāi)始事務(wù)
T3讀余額為1000
T4
讀余額為1000
T5
取出100,余額改為900
T6
提交事務(wù),余額定為900
T7匯入100,余額改為1100-
T8提交事務(wù),余額定為1100-
T9最終余額1100,更新丟失-

寫(xiě)操作加了“持續(xù)-X鎖”,讀操作加了“臨時(shí)-S鎖”,沒(méi)能阻止事務(wù)B寫(xiě),發(fā)生了提交覆蓋。


事務(wù)隔離級(jí)別:

為了解決數(shù)據(jù)庫(kù)事務(wù)并發(fā)運(yùn)行時(shí)的各種問(wèn)題數(shù)據(jù)庫(kù)系統(tǒng)提供四種事務(wù)隔離級(jí)別:
1. Serializable 串行化
2. Repeatable Read 可重復(fù)讀
3. Read Commited 可讀已提交
4. Read Uncommited 可讀未提交

并發(fā)控制:

1.數(shù)據(jù)庫(kù)系統(tǒng)采用不同的鎖類(lèi)型來(lái)實(shí)現(xiàn)以上四種隔離級(jí)別,具體的實(shí)現(xiàn)過(guò)程對(duì)用戶(hù)是透明的。用戶(hù)應(yīng)該關(guān)心的是如何選擇合適的隔離級(jí)別。
2.對(duì)于多數(shù)應(yīng)用程序,可以?xún)?yōu)先考慮把數(shù)據(jù)庫(kù)系統(tǒng)的隔離級(jí)別設(shè)為Read Committed,它能夠避免臟讀,而且具有較好的并發(fā)性能。
3.每個(gè)數(shù)據(jù)庫(kù)連接都有一個(gè)全局變量@@tx_isolation,表示當(dāng)前的事務(wù)隔離級(jí)別。JDBC數(shù)據(jù)庫(kù)連接使用數(shù)據(jù)庫(kù)系統(tǒng)默認(rèn)的隔離級(jí)別。
4.在Hibernate的配置文件中可以顯示地設(shè)置隔離級(jí)別。每一種隔離級(jí)別對(duì)應(yīng)著一個(gè)正整數(shù)。
5.需要注意的是,在受管理環(huán)境中,如果Hibernate使用的數(shù)據(jù)庫(kù)連接來(lái)自于應(yīng)用服務(wù)器提供的數(shù)據(jù)源,Hibernate不會(huì)改變這些連接的事務(wù)隔離級(jí)別。在這種情況下,應(yīng)該通過(guò)修改應(yīng)用服務(wù)器的數(shù)據(jù)源配置來(lái)修改隔離級(jí)別。

6.當(dāng)數(shù)據(jù)庫(kù)系統(tǒng)采用Red Committed隔離級(jí)別時(shí),會(huì)導(dǎo)致不可重復(fù)讀和第二類(lèi)丟失更新的并發(fā)問(wèn)題,在可能出現(xiàn)這種問(wèn)題的場(chǎng)合??梢栽趹?yīng)用程序中采用悲觀(guān)鎖或樂(lè)觀(guān)鎖來(lái)避免這類(lèi)問(wèn)題。

悲觀(guān)鎖
  正如其名,它指的是對(duì)數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來(lái)自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過(guò)程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀(guān)鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制(也只有數(shù)據(jù)庫(kù)層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪(fǎng)問(wèn)的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無(wú)法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù))。
  一個(gè)典型的依賴(lài)數(shù)據(jù)庫(kù)的悲觀(guān)鎖調(diào)用:select * from account where name=”Erica” for update這條 sql 語(yǔ)句鎖定了 account 表中所有符合檢索條件( name=”Erica” )的記錄。本次事務(wù)提交之前(事務(wù)提交時(shí)會(huì)釋放事務(wù)過(guò)程中的鎖),外界無(wú)法修改這些記錄。悲觀(guān)鎖,也是基于數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn)。
  在Hibernate使用悲觀(guān)鎖十分容易,但實(shí)際應(yīng)用中悲觀(guān)鎖是很少被使用的,因?yàn)樗看伟l(fā)送的SQL語(yǔ)句都會(huì)加上"for update"用于告訴數(shù)據(jù)庫(kù)鎖定相關(guān)數(shù)據(jù),大大限制了并發(fā)性:
樂(lè)觀(guān)鎖
  相對(duì)悲觀(guān)鎖而言,樂(lè)觀(guān)鎖機(jī)制采取了更加寬松的加鎖機(jī)制。悲觀(guān)鎖大多數(shù)情況下依靠數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn),以保證操作最大程度的獨(dú)占性。但隨之而來(lái)的就是數(shù)據(jù)庫(kù)性能的大量開(kāi)銷(xiāo),特別是對(duì)長(zhǎng)事務(wù)而言,這樣的開(kāi)銷(xiāo)往往無(wú)法承受。樂(lè)觀(guān)鎖機(jī)制在一定程度上解決了這個(gè)問(wèn)題。樂(lè)觀(guān)鎖,大多是基于數(shù)據(jù)版本(Version)記錄機(jī)制實(shí)現(xiàn)。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí),在基于數(shù)據(jù)庫(kù)表的版本解決方案中,一般是通過(guò)為數(shù)據(jù)庫(kù)表增加一個(gè)"version"字段來(lái)實(shí)現(xiàn)。
  樂(lè)觀(guān)鎖的工作原理:讀取出數(shù)據(jù)時(shí),將此版本號(hào)一同讀出,之后更新時(shí),對(duì)此版本號(hào)加一。此時(shí),將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫(kù)表對(duì)應(yīng)記錄的當(dāng)前版本信息進(jìn)行比對(duì),如果提交的數(shù)據(jù)版本號(hào)大于數(shù)據(jù)庫(kù)表當(dāng)前版本號(hào),則予以更新,否則認(rèn)為是過(guò)期數(shù)據(jù)。
Hibernate為樂(lè)觀(guān)鎖提供了3中實(shí)現(xiàn):
1. 基于version
2. 基于timestamp
3. 為遺留項(xiàng)目添加添加樂(lè)觀(guān)鎖 Hibernate為樂(lè)觀(guān)鎖提供了3中實(shí)現(xiàn)


<