亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 2522 | 回復(fù): 0
打印 上一主題 下一主題

MySQL與事務(wù) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-02-21 17:14 |只看該作者 |倒序?yàn)g覽

MySQL與事務(wù)
mysql 點(diǎn)滴
2010-01-11 20:46:17 閱讀3 評(píng)論0 字號(hào):大中
轉(zhuǎn)載: 老王

先來(lái)明確一下事務(wù)涉及的相關(guān)知識(shí):
事務(wù)都應(yīng)該具備ACID特征。所謂ACID是Atomic(原子性),Consistent(一致性),Isolated(隔離性),Durable(持續(xù)性)四個(gè)詞的首字母所寫(xiě),下面以“銀行轉(zhuǎn)帳”為例來(lái)分別說(shuō)明一下它們的含義:
原子性:組成事務(wù)處理的語(yǔ)句形成了一個(gè)邏輯單元,不能只執(zhí)行其中的一部分。換句話說(shuō),事務(wù)是不可分割的最小單元。比如:銀行轉(zhuǎn)帳過(guò)程中,必須同時(shí)從一個(gè)帳戶減去轉(zhuǎn)帳金額,并加到另一個(gè)帳戶中,只改變一個(gè)帳戶是不合理的。
一致性:在事務(wù)處理執(zhí)行前后,數(shù)據(jù)庫(kù)是一致的。也就是說(shuō),事務(wù)應(yīng)該正確的轉(zhuǎn)換系統(tǒng)狀態(tài)。比如:銀行轉(zhuǎn)帳過(guò)程中,要么轉(zhuǎn)帳金額從一個(gè)帳戶轉(zhuǎn)入另一個(gè)帳戶,要么兩個(gè)帳戶都不變,沒(méi)有其他的情況。
隔離性:一個(gè)事務(wù)處理對(duì)另一個(gè)事務(wù)處理沒(méi)有影響。就是說(shuō)任何事務(wù)都不可能看到一個(gè)處在不完整狀態(tài)下的事務(wù)。比如說(shuō),銀行轉(zhuǎn)帳過(guò)程中,在轉(zhuǎn)帳事務(wù)沒(méi)有提交之前,另一個(gè)轉(zhuǎn)帳事務(wù)只能處于等待狀態(tài)。
持續(xù)性:事務(wù)處理的效果能夠被永久保存下來(lái)。反過(guò)來(lái)說(shuō),事務(wù)應(yīng)當(dāng)能夠承受所有的失敗,包括服務(wù)器、進(jìn)程、通信以及媒體失敗等等。比如:銀行轉(zhuǎn)帳過(guò)程中,轉(zhuǎn)帳后帳戶的狀態(tài)要能被保存下來(lái)。
再來(lái)看看哪些問(wèn)題會(huì)用到事務(wù)處理:

這里不說(shuō)“銀行轉(zhuǎn)帳”的例子了,說(shuō)一個(gè)大家實(shí)際更容易遇到的“網(wǎng)上購(gòu)書(shū)”的例子。先假設(shè)一下問(wèn)題的背景:網(wǎng)上購(gòu)書(shū),某書(shū)(數(shù)據(jù)庫(kù)編號(hào)為123)只剩最后一本,而這個(gè)時(shí)候,兩個(gè)用戶對(duì)這本書(shū)幾乎同時(shí)發(fā)出了購(gòu)買(mǎi)請(qǐng)求,讓我們看看整個(gè)過(guò)程:
在具體分析之前,先來(lái)看看數(shù)據(jù)表的定義:
-------------------------------------------------------------------------------
create table book
(
    book_id unsigned int(10) not null auto_increment,
    book_name varchar(100) not null,
    book_price float(5, 2) not null, #我假設(shè)每本書(shū)的價(jià)格不會(huì)超過(guò)999.99元
    book_number int(10) not null,
    primary key (book_id)
)
type = innodb; #engine = innodb也行
-------------------------------------------------------------------------------
對(duì)于用戶甲來(lái)說(shuō),他的動(dòng)作稍微比乙快一點(diǎn)點(diǎn),其購(gòu)買(mǎi)過(guò)程所觸發(fā)的動(dòng)作大致是這樣的:
-------------------------------------------------------------------------------
1. SELECT book_number FROM book WHERE  book_id = 123;
book_number大于零,確認(rèn)購(gòu)買(mǎi)行為并更新book_number
2. UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
購(gòu)書(shū)成功
-------------------------------------------------------------------------------
而對(duì)于用戶乙來(lái)說(shuō),他的動(dòng)作稍微比甲慢一點(diǎn)點(diǎn),其購(gòu)買(mǎi)過(guò)程所觸發(fā)的動(dòng)作和甲相同:
-------------------------------------------------------------------------------
1. SELECT book_number FROM book WHERE  book_id = 123;
這個(gè)時(shí)候,甲剛剛進(jìn)行完第一步的操作,還沒(méi)來(lái)得及做第二步操作,所以book_number一定大于零
2. UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
購(gòu)書(shū)成功
-------------------------------------------------------------------------------
表面上看甲乙的操作都成功了,他們都買(mǎi)到了書(shū),但是庫(kù)存只有一本,他們?cè)趺纯赡芏汲晒δ?再看看?shù)據(jù)表里book_number的內(nèi)容,已經(jīng)變成“-1”了,這當(dāng)然是不能允許的(實(shí)際上,聲明這樣的列類(lèi)型應(yīng)該加上unsigned的屬性,以保證其不能為負(fù),這里是為了說(shuō)明問(wèn)題所以沒(méi)有這樣設(shè)置)
好了,問(wèn)題陳述清楚了,再來(lái)看看怎么利用事務(wù)來(lái)解決這個(gè)問(wèn)題,打開(kāi)MySQL手冊(cè),可以看到想用事務(wù)來(lái)保護(hù)你的SQL正確執(zhí)行其實(shí)很簡(jiǎn)單,基本就是三個(gè)語(yǔ)句:開(kāi)始,提交,回滾。
-------------------------------------------------------------------------------
開(kāi)始:START TRANSACTION或BEGIN語(yǔ)句可以開(kāi)始一項(xiàng)新的事務(wù)
提交:COMMIT可以提交當(dāng)前事務(wù),是變更成為永久變更
回滾:ROLLBACK可以回滾當(dāng)前事務(wù),取消其變更
此外,SET AUTOCOMMIT = {0 | 1}可以禁用或啟用默認(rèn)的autocommit模式,用于當(dāng)前連接。
-------------------------------------------------------------------------------
那是不是只要用事務(wù)語(yǔ)句包一下我們的SQL語(yǔ)句就能保證正確了呢?比如下面代碼:
-------------------------------------------------------------------------------
BEGIN;
SELECT book_number FROM book WHERE  book_id = 123;
// ...
UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
COMMIT;
-------------------------------------------------------------------------------
答案是否定了,這樣依然不能避免問(wèn)題的發(fā)生,如果想避免這樣的情況,實(shí)際應(yīng)該如下:
-------------------------------------------------------------------------------
BEGIN;
SELECT book_number FROM book WHERE  book_id = 123 FOR UPDATE;
// ...
UPDATE book SET book_number = book_number - 1 WHERE  book_id = 123;
COMMIT;
-------------------------------------------------------------------------------
由于加入了FOR UPDATE,所以會(huì)在此條記錄上加上一個(gè)行鎖,如果此事務(wù)沒(méi)有完全結(jié)束,那么其他的事務(wù)在使用SELECT ... FOR UPDATE請(qǐng)求的時(shí)候就會(huì)處于等待狀態(tài),直到上一個(gè)事務(wù)結(jié)束,它才能繼續(xù),從而避免了問(wèn)題的發(fā)生,需要注意的是,如果你其他的事務(wù)使用的是不帶FOR UPDATE的SELECT語(yǔ)句,將得不到這種保護(hù)。


本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u3/111930/showart_2183442.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP