就是說你定義一組數據庫操作,然后告訴數據庫說這些操作要么都成功,要么都不成功。
類似于網購買東西:你付完款,商家必須把東西寄到你的手上,期間無論是庫存、快遞、快遞員、商品質量等任何一個環節出問題,商家必須把錢退回給你。那么買東西,就是一個事務。
事務的特性有四種--ACID:
- 原子性(Atomic):這個強調事務的根本特性,一個事務內的所有操作必須像原子操作一樣,要么都成功要么都失敗,不能再拆分了。
- 一致性(Consistent):這個強調數據的完整性。就是說事務修改前后,數據符合邏輯上的完整性。就像包裹從倉庫寄到你家,手機不能變成磚頭。
- 隔離性(Insulation):這個強調的是兩個并發的事務應該是互不干擾的。雖然兩個包裹都是從北京寄到上海,但是A包裹被退回時,買家和賣家都沒必要去管B包裹是啥情況。
- 持久性(Duration):這個強調事務完成后對數據庫的影響是永久的,進入一個穩定的狀態。這個是相對于事務的實現來說的,數據庫為了維持一個事務,需要做很多緩存或者臨時性的操作。持久性就是在事務結束后,這些臨時操作都正式生效了。比如你手機確認收貨后,買手機的過程就正式完成了。對于賣家來說,再有別的問題,那就是售后的問題,而不是銷售的問題了。
相信讀者在看到事務的隔離性時,就會有疑問:兩個并發的事務不能同時修改同一條數據,那同時讀一條數據時怎么辦呢?
這就會涉及數據庫對事務的隔離控制:很明顯,不能讓兩個并發的事務同時修改同一條數據,但是照顧到性能,也不能不讓兩個事務同時讀同一條數據吧?“查詢”這么無公害的操作,何必要趕盡殺絕呢?
先看看,如果兩個事務同時操作同一條數據,會帶來哪些問題:
1.丟失更新:當前余額為:1,A事務的功能是把余額+1;B事務的功能是把余額-1;它倆同時讀到了余額為0,悲劇就發生了。。。。
2.臟讀:A事務正在把userName改成‘bizi’,還沒有提交,B事務來讀取userName,得到了‘bizi’,但是A事務在修改age時拋了異常,因此回滾,結果B事務就悲劇了。。。。
3.幻讀:A事務讀了一下當前的訂單數目,B事務過來新增加了一個訂單,A事務又讀了一次訂單數,讀了兩次竟然結果不一樣,鬧鬼了。。。?
4.不可重復讀:A事務讀取了某條數據,B事務過來修改了這條數據并提交,A事務再讀的時候,就發現跟剛剛不一樣哎。。。
不可重復讀跟臟讀的區別:
? ? 臟讀讀取的是未提交的數據,很有可能是無效的數據。而不可重復讀讀取的是提交之后的數據,最起碼第二次讀對了
不可重復讀跟幻讀的區別:
? ? 幻讀讀的是一整條記錄,而不可重復讀針對的是某一個或幾個特定字段。
那么為了避免這種情況,數據庫就設定了幾種隔離級別,供我們使用:
1.串行化(Serializable):不允許事務并發,大家排好隊,上一個事務提交(或回滾)了,下一個事務再執行。
2.可重復讀(Repeatable-Read):同一事務前后兩次的讀,保證數據一致。意思就是:讀的時候,不允許別人寫。但是允許別人插入別的數據,因此不能避免幻讀。
3.讀已提交(Read Commited):只允許事務讀取被其他事務提交的數據。意思就是:如果當前事務是修改數據,那么不允許讀。因此避免臟讀,但是不能避免幻讀和不可重復讀。
4.讀未提交(Read Uncommitted):允許事務讀取其他事務還未提交的數據。因此上述問題都會發生。
一個表格可以說明一切(來源于@jiajialin:http://blog.csdn.net/jialinqiang/article/details/8723044):


來自為知筆記(Wiz)