一致份、事務(wù)的概念
事務(wù)指邏輯上的一組操作逻族,組成這組操作的各個單元,要不全部成功束昵,要不全部不成功拔稳。
例如:A——B轉(zhuǎn)帳,對應(yīng)于如下兩條sql語句
update from account set money=money+100 where name=‘b’;
update from account set money=money-100 where name=‘a(chǎn)’;
二锹雏、事務(wù)的使用
- JDBC開啟事務(wù)的命令
start transaction 開啟事務(wù)
Rollback 回滾事務(wù)
Commit 提交事務(wù) - 當Jdbc程序向數(shù)據(jù)庫獲得一個Connection對象時巴比,默認情況下這個Connection對象會自動向數(shù)據(jù)庫提交在它上面發(fā)送的SQL語句。若想關(guān)閉這種默認提交方式礁遵,讓多條SQL在一個事務(wù)中執(zhí)行轻绞,可使用下列語句:
- JDBC控制事務(wù)語句
Connection.setAutoCommit(false);
Connection.rollback();
Connection.commit();
三、事務(wù)的特性
- 原子性(Atomicity)?原子性是指事務(wù)是一個不可分割的工作單位佣耐,事務(wù)中的操作要么都發(fā)生政勃,要么都不發(fā)生。
- 一致性(Consistency)?事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另外一個一致性狀態(tài)兼砖。
- 隔離性(Isolation)?事務(wù)的隔離性是多個用戶并發(fā)訪問數(shù)據(jù)庫時奸远,數(shù)據(jù)庫為每一個用戶開啟的事務(wù),不能被其他事務(wù)的操作數(shù)據(jù)所干擾讽挟,多個并發(fā)事務(wù)之間要相互隔離懒叛。
- 持久性(Durability)?持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的耽梅,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響薛窥。
以談戀愛為例子理解:
A:原子性,即要么泡妞成功褐墅,要么泡妞不成功拆檬,絕對不能出現(xiàn)曖昧不清的情況
C:一致性洪己,即如果對方對你好,你就不能耍脾氣竟贯,也要對對方好答捕,狀態(tài)要保持一致
I:隔離性,談戀愛期間錢歸錢屑那,愛歸愛拱镐,兩者不能混淆,愛不應(yīng)收到窮富的干擾
D:持久性持际,這個你懂的沃琅。。蜘欲。益眉。。姥份。郭脂。別誤解了,我指的是戀愛這個應(yīng)該是一輩子的澈歉,是永久性的
出自http://www.zhihu.com/question/30272728
四罐脊、事務(wù)的隔離級別
- 多個線程開啟各自事務(wù)操作數(shù)據(jù)庫中數(shù)據(jù)時吏恭,數(shù)據(jù)庫系統(tǒng)要負責隔離操作尉咕,以保證各個線程在獲取數(shù)據(jù)時的準確性蟋恬。如果不考慮隔離性,可能會引發(fā)如下問題:
a. 臟讀:指一個事務(wù)讀取了另外一個事務(wù)未提交的數(shù)據(jù)
假設(shè)A向B轉(zhuǎn)帳100元涡尘,對應(yīng)sql語句如下所示
1.update account set money=money+100 while name=‘b’;
2.update account set money=money-100 while name=‘a(chǎn)’;
當?shù)?條sql執(zhí)行完忍弛,第2條還沒執(zhí)行(A未提交時),如果此時B查詢自己的帳戶考抄,就會發(fā)現(xiàn)自己多了100元錢剧罩。如果A等B走后再回滾,B就會損失100元座泳。
b. 不可重復讀:在一個事物內(nèi)讀取表中的某一行數(shù)據(jù)惠昔,多次讀取結(jié)果不同。
例如銀行想查詢A帳戶余額挑势,第一次查詢A帳戶為200元镇防,此時A向帳戶內(nèi)存了100元并提交了,銀行接著又進行了一次查詢潮饱,此時A帳戶為300元了来氧。銀行兩次查詢不一致,可能就會很困惑,不知道哪次查詢是準的啦扬。
和臟讀的區(qū)別是中狂,臟讀是讀取前一事務(wù)未提交的臟數(shù)據(jù),不可重復讀是重新讀取了前一事務(wù)已提交的數(shù)據(jù)扑毡。
很多人認為這種情況就對了胃榕,無須困惑,當然是后面的為準瞄摊。我們可以考慮這樣一種情況勋又,比如銀行程序需要將查詢結(jié)果分別輸出到電腦屏幕和寫到文件中,結(jié)果在一個事務(wù)中針對輸出的目的地换帜,進行的兩次查詢不一致楔壤,導致文件和屏幕中的結(jié)果不一致,銀行工作人員就不知道以哪個為準了惯驼。
c. 虛讀:是指在一個事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù)蹲嚣,導致前后讀取不一致
如丙存款100元未提交,這時銀行做報表統(tǒng)計account表中所有用戶的總額為500元祟牲,然后丙提交了端铛,這時銀行再統(tǒng)計發(fā)現(xiàn)帳戶為600元了,造成虛讀同樣會使銀行不知所措疲眷,到底以哪個為準。
2. 數(shù)據(jù)庫四種隔離級別:
a. Serializable:可避免臟讀您朽、不可重復讀狂丝、虛讀情況的發(fā)生。(串行化)它會鎖表哗总,可以解決所有問題.
b. Repeatable read:可避免臟讀几颜、不可重復讀情況的發(fā)生。(可重復讀)可以解決臟讀讯屈,可以解決不可重復讀,不能解決虛讀.
c. Read committed:可避免臟讀情況發(fā)生蛋哭。(讀已提交)可以解決臟讀,其它解決不了
d. Read uncommitted:最低級別涮母,以上情況均無法保證谆趾。(讀未提交)什么問題也解決不了
安全性:serializable > repeatable read > read committed > read uncommitted
性能 :serializable < repeatable read < read committed < read uncommitted
結(jié)論: 實際開發(fā)中,通常不會選擇 serializable 和 read uncommitted 叛本,mysql默認隔離級別 repeatable read 沪蓬,oracle默認隔離級別 read committed
3. 設(shè)置隔離級別
a. mysql中設(shè)置
i. 查看事務(wù)隔離級別
select @@tx_isolation 查詢當前事務(wù)隔離級別
mysql中默認的事務(wù)隔離級別是 Repeatable read.
ii. 擴展:oracle 中默認的事務(wù)隔離級別是 Read committed
iii. mysql中怎樣設(shè)置事務(wù)隔離級別
set session transaction isolation level 設(shè)置事務(wù)隔離級別
b. jdbc中設(shè)置
i. 在jdbc中設(shè)置事務(wù)隔離級別
使用java.sql.Connection接口中提供的方法
void setTransactionIsolation(int level) throws SQLException
ii. 參數(shù)level可以取以下值:
level - 以下 Connection 常量之一:
Connection.TRANSACTION_READ_UNCOMMITTED、
Connection.TRANSACTION_READ_COMMITTED来候、
Connection.TRANSACTION_REPEATABLE_READ
Connection.TRANSACTION_SERIALIZABLE跷叉。
iii. 注意,不能使用 Connection.TRANSACTION_NONE,因為它指定了不受支持的事務(wù)云挟。