第 20 章 管理事務(wù)功能

本章介紹什么是事務(wù)處理以及如何利用 COMMIT 和 ROLLBACK 語句來管理事務(wù)處理

20.1 事務(wù)處理

事務(wù)處理可以用來維護(hù)數(shù)據(jù)庫的完整性猜敢,它保證成批的 SQL 操作要么完全執(zhí)行,要么完全不執(zhí)行
正如第 12 章所述枫攀,關(guān)系數(shù)據(jù)庫設(shè)計(jì)把數(shù)據(jù)存儲(chǔ)在多個(gè)表中凯旭,使數(shù)據(jù)更容易操縱惫霸、維護(hù)和重用封恰。不用深究如何以及為什么進(jìn)行關(guān)系數(shù)據(jù)庫設(shè)計(jì),在某種程度上說越庇,設(shè)計(jì)良好的數(shù)據(jù)庫模式都是關(guān)聯(lián)的罩锐。
前面章中使用的 Orders 表就是一個(gè)很好的例子。
訂單存儲(chǔ)在 Orders 和 OrderItems 兩個(gè)表中:Orders 存儲(chǔ)實(shí)際的訂單悦荒,而 OrderItems 存儲(chǔ)訂購的各項(xiàng)物品唯欣。這兩個(gè)表使用主鍵互相關(guān)聯(lián)。這兩個(gè)表又與包含客戶和產(chǎn)品信息的其他表相關(guān)聯(lián)搬味。
給系統(tǒng)添加訂單的過程如下:
1.檢查數(shù)據(jù)庫中是否存在相應(yīng)的客戶境氢,如果不存在蟀拷,添加他/她
2.檢索客戶的 ID
3.添加一行到 Orders 表,把它與客戶 ID 關(guān)聯(lián)
4.檢索 Orders 表中賦予的新訂單 ID
5.對(duì)于訂購的每個(gè)物品在 OrderItems 表中添加一行萍聊,通過檢索出來的 ID 把它與 Orders 表關(guān)聯(lián)(以及通過產(chǎn)品 ID 與 Products 表關(guān)聯(lián))

假如由于某種數(shù)據(jù)庫故障(如超出磁盤空間问芬、安全限制、表鎖等)阻止了這個(gè)過程的完成寿桨。那么數(shù)據(jù)庫中的數(shù)據(jù)會(huì)出現(xiàn)什么情況此衅?

  • 如果故障發(fā)生在添加了客戶之后,Orders 表添加之前亭螟,那么不會(huì)有什么問題
    • 因?yàn)槟承┛蛻魶]有訂單是完全合法的
  • 如果故障發(fā)生在 Orders 行插入之后挡鞍,OrderItems 添加之前,數(shù)據(jù)庫中則會(huì)有一個(gè)空訂單
  • 如果系統(tǒng)在添加 OrderItems 行之中出現(xiàn)故障预烙,數(shù)據(jù)庫中存在不完整的訂單墨微,而且還不知道

這就需要使用事務(wù)處理:事務(wù)處理是一種機(jī)制,用來管理必須成批執(zhí)行的 SQL 操作扁掸,以保證數(shù)據(jù)庫不包含不完整的操作結(jié)果
利用事務(wù)處理翘县,可以保證一組操作不會(huì)中途停止,它們或者作為整體執(zhí)行谴分,或者完全不執(zhí)行
如果沒有錯(cuò)誤發(fā)生锈麸,整組語句提交給(寫到)數(shù)據(jù)庫表;
如果發(fā)生錯(cuò)誤牺蹄,則進(jìn)行回退(撤銷)以恢復(fù)數(shù)據(jù)庫到某個(gè)已知且安全的狀態(tài)
因此忘伞,請(qǐng)看相同的例子,這次我們說明過程如何工作:
1.檢查數(shù)據(jù)庫中是否存在相應(yīng)的客戶钞馁,如果不存在虑省,添加他/她
2.提交客戶信息
3.檢索客戶的 ID
4.添加一行到 Orders 表
5.如果在添加行到 Orders 表時(shí)出現(xiàn)故障匿刮,則回退
6.檢索 Orders 表中賦予的新訂單 ID
7.對(duì)于訂購的每項(xiàng)物品僧凰,添加新行到 OrderItems 表
8.如果在添加新行到 OrderItems 時(shí)出現(xiàn)故障,回退所有添加的 OrderItems 行和 Orders 行

有關(guān)事務(wù)處理需要知道的幾個(gè)術(shù)語:

  • 事務(wù)指一組 SQL 語句
  • 回退指撤銷指定 SQL 語句的過程
  • 提交指將未存儲(chǔ)的 SQL 語句結(jié)果寫入數(shù)據(jù)庫表
  • 保留點(diǎn)指事務(wù)處理中設(shè)置的臨時(shí)占位符熟丸,你可以對(duì)它發(fā)布回退(與回退整個(gè)事務(wù)處理不同)

可以回退哪些語句训措?
事務(wù)處理用來管理 INSERT、UPDATE 和 DELETE 語句
不能回退 SELECT 語句光羞,也不能回退 CREATE 或 DROP 操作

20.2 控制事務(wù)處理

下面討論事務(wù)處理的管理中所涉及的問題
管理事務(wù)處理的關(guān)鍵在于將 SQL 語句組分解為邏輯塊绩鸣,并明確規(guī)定數(shù)據(jù)何時(shí)應(yīng)該回退,何時(shí)不應(yīng)該回退

有的 DBMS 要求明確標(biāo)識(shí)事務(wù)處理塊的開始和結(jié)束纱兑,如在 SQL Server 中呀闻,標(biāo)識(shí)如下:
BEGIN TRANSACTION
...
COMMIT TRANSACTION

MySQL 中等同的代碼為:
START TRANSATCION
...

在 Oracle 數(shù)據(jù)庫中,沒有提供開始事務(wù)處理語句潜慎,所有的事務(wù)都是隱式開始的捡多,也就是說在 Oracle 中蓖康,用戶不可以顯示使用命令來開始一個(gè)事務(wù)
Oracle 任務(wù)第一條修改數(shù)據(jù)庫的語句,或者一些要求事務(wù)處理的場(chǎng)合都是事務(wù)的隱式開始

20.2.1 使用 ROLLBACK

SQL 的 ROLLBACK 命令用來回退(撤銷)SQL 語句垒手,請(qǐng)看下面的語句:

DELETE FROM Orders;
ROLLBACK;

20.2.2 使用 COMMIT

一般的 SQL 語句都是直接針對(duì)數(shù)據(jù)庫表執(zhí)行和編寫的蒜焊,這就是所謂的隱含提交,也就是提交(寫或保存)操作都是自動(dòng)進(jìn)行的
但是科贬,在事務(wù)處理塊中泳梆,提交不會(huì)隱含地進(jìn)行,為進(jìn)行明確的提交榜掌,需要使用 COMMIT 語句优妙。

看一個(gè) SQL Server 的例子:

BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION

為在 Oracle 中完成相同的工作,可如下進(jìn)行:

DELETE OrderItems WHERE order_num = 12345;
DELETE Orders WHERE order_num = 12345;
COMMIT;

20.2.3 使用保留點(diǎn)

簡(jiǎn)單的 ROLLBACK 和 COMMIT 語句就可以寫入或撤銷整個(gè)事務(wù)處理憎账。
但是鳞溉,這只是針對(duì)簡(jiǎn)單的事務(wù)處理才能這樣做,更復(fù)雜的事務(wù)處理可能需要部分提交或回退
例如鼠哥,前面描述的添加訂單的過程為事務(wù)處理熟菲。如果發(fā)生錯(cuò)誤,只需要返回到添加 Orders 行之前即可朴恳。不需要回退到 Customers 表(如果存在的話)抄罕。

為了完成這樣的事情,必須在事務(wù)處理中合適的位置放置占位符于颖。這樣呆贿,如果需要回退,就可以回退到某個(gè)占位符森渐,
在 SQL 中做入,這些占位符稱為保留點(diǎn)
為了在 MySQL 和 Oracle 中創(chuàng)建占位符,可如下使用 SAVEPOINT 語句:

SAVEPOINT delete1;

每個(gè)保留點(diǎn)都取標(biāo)識(shí)它的唯一名字同衣,以便在回退時(shí)竟块,DBMS 知道要回退到何處。
為了回退到上面給出的保留點(diǎn)耐齐,在 MySQL 和 Oracle 中浪秘,可如下進(jìn)行:

ROLLBACK TO delete1;

保留點(diǎn)越多越好:保留點(diǎn)越多,就越能按自己的意愿靈活地進(jìn)行回退

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末埠况,一起剝皮案震驚了整個(gè)濱河市耸携,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辕翰,老刑警劉巖夺衍,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異喜命,居然都是意外死亡沟沙,警方通過查閱死者的電腦和手機(jī)的畴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尝胆,“玉大人丧裁,你說我怎么就攤上這事『危” “怎么了煎娇?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贪染。 經(jīng)常有香客問我缓呛,道長(zhǎng),這世上最難降的妖魔是什么杭隙? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任哟绊,我火速辦了婚禮,結(jié)果婚禮上痰憎,老公的妹妹穿的比我還像新娘票髓。我一直安慰自己,他們只是感情好铣耘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布洽沟。 她就那樣靜靜地躺著,像睡著了一般蜗细。 火紅的嫁衣襯著肌膚如雪裆操。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天炉媒,我揣著相機(jī)與錄音踪区,去河邊找鬼。 笑死吊骤,一個(gè)胖子當(dāng)著我的面吹牛缎岗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播水援,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼密强,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼茅郎!你這毒婦竟也來了蜗元?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤系冗,失蹤者是張志新(化名)和其女友劉穎奕扣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掌敬,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惯豆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年池磁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楷兽。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡地熄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芯杀,到底是詐尸還是另有隱情端考,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布揭厚,位于F島的核電站却特,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏筛圆。R本人自食惡果不足惜裂明,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望太援。 院中可真熱鬧闽晦,春花似錦、人聲如沸提岔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唧垦。三九已至捅儒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間振亮,已是汗流浹背巧还。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坊秸,地道東北人麸祷。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像褒搔,于是被迫代替她去往敵國(guó)和親阶牍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容