日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

数据库事务与锁详解

發布時間:2024/6/30 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库事务与锁详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、數據庫事務


?

  1.什么是事務?

  這里引用事務的定義,事務是指作為單個邏輯工作單元執行的一系列操作,要么完全地執行,要么完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。通過將一組相關操作組合為一個要么全部成功要么全部失敗的單元,可以簡化錯誤恢復并使應用程序更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。事務是數據庫運行中的一個邏輯工作單位,由DBMS中的事務管理子系統負責事務的處理。

  舉個簡單的例子:銀行轉賬的情況,A轉賬給B 1000塊。    

    1.A的賬號減少1000元。

    2.B的賬號增加1000元。

這兩個步驟都執行成功,則代表事務成功。如果執行1步驟成功,但是第二步驟執行失敗,則事務會進行回滾,

  2.事務的4個特性  

 ⑴ 原子性(Atomicity)
  原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,這和前面兩篇博客介紹事務的功能是一樣的概念,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。
 ⑵ 一致性(Consistency)
  一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處于一致性狀態。
  拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。

 ⑶ 隔離性(Isolation)
  隔離性是當多個用戶并發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個并發事務之間要相互隔離。
  即要達到這么一種效果:對于任意兩個并發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在并發地執行。

 ⑷ 持久性(Durability)
  持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
  例如我們在使用JDBC操作數據庫時,在提交事務方法后,提示用戶事務操作完成,當我們程序執行完成直到看到提示后,就可以認定事務以及正確提交,即使這時候數據庫出現了問題,也必須要將我們的事務完全執行完成,否則就會造成我們看到提示事務處理完畢,但是數據庫因為故障而沒有執行事務的重大錯誤。

  3.事務的隔離性  

  當多個線程都開啟事務操作數據庫中的數據時,數據庫系統要能進行隔離操作,以保證各個線程獲取數據的準確性。看一下數據沒有使用隔離時會產生的問題。

  (1)臟讀

  臟讀就是指當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。因為這個 數據是還沒有提交的數據,那么另外一個事務讀到的這個數據是臟數據,依據臟數據所做的操作可能是不正確的。

  舉個例子:用戶A向用戶B轉賬1000元,A賬號為5000元,分為兩條sql執行,兩個步驟

    1.A的賬號的錢減少1000元。

    2.B的賬號的錢增加1000元。

  當T1事務執行到1步驟的時候,T2事務開始讀取A的賬號的數據,發現是減少后的數據即5000-1000。之后如果T1事務(轉賬)如果發生回滾,那么T2再次讀取A的賬號的數據實際上就還是5000,并沒有變化。這就是有問題了。

  (2)不可重復讀

  不可重復讀是指在數據庫訪問中,一個事務范圍內兩個相同的查詢卻返回了不同數據。

舉個例子:T1:小明讀取自己賬號有5000元,開始準備購物2000元的手機。

   T2:小明的老婆取走了小明的賬號4000元。

  這里小明第一次讀取自己賬號發現有5000塊可以購物,這時候T2提交了,在購物的時候就會發現錢不足了,前后讀取的數據不一致。

? ? ? ?不可重復讀和臟讀的區別是,臟讀是某一事務讀取了另一個事務未提交的臟數據,而不可重復讀則是讀取了前一事務提交的數據。在某些情況下,不可重復讀并不是問題,比如我們多次查詢某個數據當然以最后查詢得到的結果為主。但在另一些情況下就有可能發生問題。

  (3)虛讀(幻讀)

 ? ?幻讀是指當事務不是獨立執行時發生的一種現象。幻讀和不可重復讀有點像,只是針對的不是數據的值而是數據的數量。此種異常是一個事務在兩次查詢的過程中數據的數量不同,讓人以為發生幻覺。 

   T1:小明查看自己的賬號消費記錄有10條,總賬單1000元,準備打印賬單。

   T2:小明的老婆用小明的卡消費100元。

? ? ? ?這里小明第一次看消費記錄是10條,總消費是1000元,這時候T2發生并提交了(消費),再次打印賬單時就是看到消費記錄是11條,賬單是1100了,小明就以為產生了幻覺。

  4.數據庫的隔離級別

  數據庫事務的隔離級別有4個,由低到高依次為Read uncommitted?、Read committed?、Repeatable read?、Serializable?,這四個級別可以逐個解決臟讀?、不可重復讀?、幻讀?這幾類問題,1表示可以解決,0代表可能會出現。         

?

?臟讀不可重復讀幻讀
Read uncommitted000
Read committed100
Repeatable read110
Serializable111
  • 讀未提交(Read Uncommitted):該隔離級別指即使一個事務的更新語句沒有提交,但是別的事務可以讀到這個改變,幾種異常情況都可能出現。極易出錯,沒有安全性可言,基本不會使用。

  • 讀已提交(Read Committed):該隔離級別指一個事務只能看到其他事務的已經提交的更新,看不到未提交的更新,消除了臟讀,這是大多數數據庫的默認隔離級別,如Oracle,Sqlserver。

  • 可重復讀(Repeatable Read):該隔離級別指一個事務中進行兩次或多次同樣的對于數據內容的查詢,得到的結果是一樣的,但不保證對于數據條數的查詢是一樣的,只要存在讀改行數據就禁止寫,消除了不可重復讀,這是Mysql數據庫的默認隔離級別。

  • 串行化(Serializable):意思是說這個事務執行的時候不允許別的事務并發執行.完全串行化的讀,只要存在讀就禁止寫,但可以同時讀,消除了幻讀。這是事務隔離的最高級別,雖然最安全最省心,但是效率太低,一般不會用。

二、數據庫鎖

  數據庫鎖一般可以分為兩類:悲觀鎖與樂觀鎖。

  1.為什么需要鎖

  在多用戶環境中,在同一時間可能會有多個用戶更新相同的記錄,這會產生沖突。當并發事務同時訪問一個資源時,有可能導致數據不一致,因此需要一種機制來將數據訪問順序化,以保證數據庫數據的一致性。鎖就是其中的一種機制。

  樂觀并發控制(樂觀鎖)和悲觀并發控制(悲觀鎖)是并發控制主要采用的技術手段。

  2.鎖的分類 

  (1)按操作劃分,可分為DML鎖、DDL鎖

  DML鎖(data locks,數據鎖),用于保護數據的完整性,其中包括行級鎖(Row Locks (TX鎖))、表級鎖(table lock(TM鎖))。 DDL鎖(dictionary locks,數據字典鎖),用于保護數據庫對象的結構,如表、索引等的結構定義。其中包排他DDL鎖(Exclusive DDL lock)、共享DDL鎖(Share DDL lock)、可中斷解析鎖(Breakable parse locks。

  (2)按使用方式劃分,可分為樂觀鎖、悲觀鎖

  3.樂觀鎖

  (1)概述    

    相對而言,樂觀鎖機制采取了更加寬松的加鎖機制。樂觀鎖,就是認為每次操作數據的時候都沒有其他事務在修改。樂觀鎖并沒有使用數據庫的鎖機制。

  (2)樂觀鎖實現 

  版本號(記為version):就是給數據增加一個版本標識,當讀取數據時,將版本標識的值一同讀出,數據每更新一次,同時對版本標識進行更新。當我們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的版本標識進行比對,如果數據庫表當前版本號與第一次取出來的版本標識值相等,則予以更新,否則認為是過期數據。

    時間戳(timestamp):和版本號基本一樣,只是通過時間戳來判斷而已,注意時間戳要使用數據庫服務器的時間戳不能是業務系統的時間。

  待更新字段:和版本號方式相似,只是不增加額外字段,直接使用有效數據字段做版本控制信息,因為有時候我們可能無法改變舊系統的數據庫表結構。假設有個待更新字段叫count,先去讀取這個count,更新的時候去比較數據庫中count的值是不是我期望的值(即開始讀的值),如果是就把我修改的count的值更新到該字段,否則更新失敗。java的基本類型的原子類型對象如AtomicInteger就是這種思想。

  ? ?(3)? 優缺點

  樂觀并發控制相信事務之間的數據競爭(data race)的概率是比較小的,因此盡可能直接做下去,直到提交的時候才去鎖定,所以不會產生任何鎖和死鎖。但如果直接簡單這么做,還是有可能會遇到不可預期的結果,例如兩個事務都讀取了數據庫的某一行,經過修改以后寫回數據庫,這時就遇到了問題。

  4.悲觀鎖

?    (1)概述

      顧名思義,就是很悲觀,它對于數據被外界修改持保守態度,認為數據隨時會修改,所以整個數據處理中需要將數據加鎖。

    (2)悲觀鎖按照使用性質劃分     

  共享鎖(Share locks簡記為S鎖):也稱讀鎖,事務A對對象T加s鎖,其他事務也只能對T加S,多個事務可以同時讀,但不能有寫操作,直到A釋放S鎖。

  排它鎖(Exclusivelocks簡記為X鎖):也稱寫鎖,事務A對對象T加X鎖以后,其他事務不能對T加任何鎖,只有事務A可以讀寫對象T直到A釋放X鎖。

  更新鎖(簡記為U鎖):用來預定要對此對象施加X鎖,它允許其他事務讀,但不允許再施加U鎖或X鎖;當被讀取的對象將要被更新時,則升級為X鎖,主要是用來防止死鎖的。因為使用共享鎖時,修改數據的操作分為兩步,首先獲得一個共享鎖,讀取數據,然后將共享鎖升級為排它鎖,然后再執行修改操作。這樣如果同時有兩個或多個事務同時對一個對象申請了共享鎖,在修改數據的時候,這些事務都要將共享鎖升級為排它鎖。這些事務都不會釋放共享鎖而是一直等待對方釋放,這樣就造成了死鎖。如果一個數據在修改前直接申請更新鎖,在數據修改的時候再升級為排它鎖,就可以避免死鎖。 

     (3)悲觀鎖按照作用范圍劃分:

      行鎖,表鎖,頁鎖。

轉載于:https://www.cnblogs.com/hkzklt/p/9004190.html

總結

以上是生活随笔為你收集整理的数据库事务与锁详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。