Mysql 事務(wù)的講解

來源轉(zhuǎn)載自:http://www.cnblogs.com/ymy124/p/3718439.html

MySQL的事務(wù)支持不是綁定在MySQL服務(wù)器本身姨伤,而是與存儲引擎相關(guān)1.MyISAM:不支持事務(wù)哨坪,用于只讀程序提高性能 2.InnoDB:支持ACID事務(wù)、行級鎖乍楚、并發(fā) 3.Berkeley DB:支持事務(wù)

一個事務(wù)是一個連續(xù)的一組數(shù)據(jù)庫操作当编,就好像它是一個單一的工作單元進行。換言之徒溪,永遠不會是完整的事務(wù)忿偷,除非該組內(nèi)的每個單獨的操作是成功的。如果在事務(wù)的任何操作失敗臊泌,則整個事務(wù)將失敗鲤桥。
實際上,會俱樂部許多SQL查詢到一個組中渠概,將執(zhí)行所有的人都一起作為事務(wù)的一部分茶凳。
事務(wù)的特性: 事務(wù)有以下四個標(biāo)準(zhǔn)屬性的縮寫ACID,通常被稱為:
原子性: 確保工作單元內(nèi)的所有操作都成功完成播揪,否則事務(wù)將被中止在故障點慧妄,和以前的操作將回滾到以前的狀態(tài)。
一致性: 確保數(shù)據(jù)庫正確地改變狀態(tài)后剪芍,成功提交的事務(wù)塞淹。
隔離性: 使事務(wù)操作彼此獨立的和透明的。
持久性: 確保提交的事務(wù)的結(jié)果或效果的系統(tǒng)出現(xiàn)故障的情況下仍然存在罪裹。
在MySQL中饱普,事務(wù)開始使用COMMIT或ROLLBACK語句開始工作和結(jié)束运挫。開始和結(jié)束語句的SQL命令之間形成了大量的事務(wù)。
COMMIT & ROLLBACK: 這兩個關(guān)鍵字提交和回滾主要用于MySQL的事務(wù)套耕。
當(dāng)一個成功的事務(wù)完成后谁帕,發(fā)出COMMIT命令應(yīng)使所有參與表的更改才會生效。
如果發(fā)生故障時冯袍,應(yīng)發(fā)出一個ROLLBACK命令返回的事務(wù)中引用的每一個表到以前的狀態(tài)匈挖。
可以控制的事務(wù)行為稱為AUTOCOMMIT設(shè)置會話變量。如果AUTOCOMMIT設(shè)置為1(默認值)康愤,然后每一個SQL語句(在事務(wù)與否)被認為是一個完整的事務(wù)儡循,并承諾在默認情況下,當(dāng)它完成征冷。 AUTOCOMMIT設(shè)置為0時择膝,發(fā)出SET AUTOCOMMIT =0命令,在隨后的一系列語句的作用就像一個事務(wù)检激,直到一個明確的COMMIT語句時肴捉,沒有活動的提交。
可以通過使用mysql_query()函數(shù)在PHP中執(zhí)行這些SQL命令叔收。
通用事務(wù)例子 這一系列事件是獨立于所使用的編程語言齿穗,可以建立在任何使用的語言來創(chuàng)建應(yīng)用程序的邏輯路徑〗嚷桑可以通過使用mysql_query()函數(shù)在PHP中執(zhí)行這些SQL命令缤灵。
BEGIN WORK開始事務(wù)發(fā)出SQL命令
發(fā)出一個或多個SQL命令,如SELECT蓝晒,INSERT腮出,UPDATE或DELETE
檢查是否有任何錯誤,一切都依據(jù)的需要芝薇。
如果有任何錯誤胚嘲,那么問題ROLLBACK命令,否則發(fā)出COMMIT命令洛二。
在MySQL中的事務(wù)安全表類型:
如果打算使用MySQL事務(wù)編程馋劈,那么就需要一種特殊的方式創(chuàng)建表。有很多支持事務(wù)但最流行的是InnoDB表類型晾嘶。
從源代碼編譯MySQL時妓雾,InnoDB表支持需要特定的編譯參數(shù)。如果MySQL版本沒有InnoDB支持垒迂,請互聯(lián)網(wǎng)服務(wù)提供商建立一個版本的MySQL支持InnoDB表類型械姻,或者下載并安裝Windows或Linux/UNIX的MySQL-Max二進制分發(fā)和使用的表類型在開發(fā)環(huán)境中。如果MySQL安裝支持InnoDB表机断,只需添加一個的TYPE=InnoDB 定義表創(chuàng)建語句楷拳。例如绣夺,下面的代碼創(chuàng)建InnoDB表tcount_tbl:

代碼如下
復(fù)制代碼

root@host# mysql -u root -p password;Enter password:*******mysql> use TUTORIALS;Database changedmysql> create table tcount_tbl -> ( -> tutorial_author varchar(40) NOT NULL, -> tutorial_count INT -> ) TYPE=InnoDB;Query OK, 0 rows affected (0.05 sec)

可以使用其他GEMINI或BDB表類型,但它取決于您的安裝欢揖,如果它支持這兩種類型陶耍。
由于項目設(shè)計里面,牽扯到了金錢的轉(zhuǎn)移她混,于是就要用到MYSQL的事務(wù)處理烈钞,來保證一組處理結(jié)果的正確性。用了事務(wù)坤按,就不可避免的要犧牲一部分速度毯欣,來保證數(shù)據(jù)的正確性。只有InnoDB支持事務(wù)
事務(wù) ACID Atomicity(原子性)晋涣、Consistency(穩(wěn)定性)、Isolation(隔離性)沉桌、Durability(可靠性)
1谢鹊、事務(wù)的原子性一組事務(wù),要么成功留凭;要么撤回佃扼。
2、穩(wěn)定性有非法數(shù)據(jù)(外鍵約束之類)蔼夜,事務(wù)撤回兼耀。
3、隔離性事務(wù)獨立運行求冷。一個事務(wù)處理后的結(jié)果瘤运,影響了其他事務(wù),那么其他事務(wù)會撤回匠题。事務(wù)的100%隔離拯坟,需要犧牲速度。
4韭山、可靠性軟郁季、硬件崩潰后,InnoDB數(shù)據(jù)表驅(qū)動會利用日志文件重構(gòu)修改钱磅∶瘟眩可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit選項 決定什么時候吧事務(wù)保存到日志里盖淡。開啟事務(wù)START TRANSACTION 或 BEGIN
提交事務(wù)(關(guān)閉事務(wù))COMMIT
放棄事務(wù)(關(guān)閉事務(wù))ROLLBACK
折返點SAVEPOINT adqoo_1ROLLBACK TO SAVEPOINT adqoo_1發(fā)生在折返點 adqoo_1 之前的事務(wù)被提交年柠,之后的被忽略
事務(wù)的終止
設(shè)置“自動提交”模式SET AUTOCOMMIT = 0每條SQL都是同一個事務(wù)的不同命令,之間由 COMMIT 或 ROLLBACK隔開掉線后褪迟,沒有 COMMIT 的事務(wù)都被放棄
事務(wù)鎖定模式
系統(tǒng)默認: 不需要等待某事務(wù)結(jié)束彪杉,可直接查詢到結(jié)果毅往,但不能再進行修改、刪除派近。缺點:查詢到的結(jié)果攀唯,可能是已經(jīng)過期的。優(yōu)點:不需要等待某事務(wù)結(jié)束渴丸,可直接查詢到結(jié)果侯嘀。
需要用以下模式來設(shè)定鎖定模式
1、SELECT …… LOCK IN SHARE MODE(共享鎖)查詢到的數(shù)據(jù)谱轨,就是數(shù)據(jù)庫在這一時刻的數(shù)據(jù)(其他已commit事務(wù)的結(jié)果戒幔,已經(jīng)反應(yīng)到這里了)SELECT 必須等待,某個事務(wù)結(jié)束后才能執(zhí)行
2土童、SELECT …… FOR UPDATE(排它鎖)例如 SELECT * FROM tablename WHERE id<200那么id<200的數(shù)據(jù)诗茎,被查詢到的數(shù)據(jù),都將不能再進行修改献汗、刪除敢订、SELECT …… LOCK IN SHARE MODE操作一直到此事務(wù)結(jié)束
共享鎖 和 排它鎖 的區(qū)別:在于是否阻斷其他客戶發(fā)出的 SELECT …… LOCK IN SHARE MODE命令
3、INSERT / UPDATE / DELETE所有關(guān)聯(lián)數(shù)據(jù)都會被鎖定罢吃,加上排它鎖
4楚午、防插入鎖例如 SELECT * FROM tablename WHERE id>200那么id>200的記錄無法被插入
5、死鎖自動識別死鎖先進來的進程被執(zhí)行尿招,后來的進程收到出錯消息矾柜,并按ROLLBACK方式回滾innodb_lock_wait_timeout = n 來設(shè)置最長等待時間,默認是50秒
事務(wù)隔離模式
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVELREAD UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE1就谜、不帶SESSION怪蔑、GLOBAL的SET命令只對下一個事務(wù)有效2、SET SESSION為當(dāng)前會話設(shè)置隔離模式3丧荐、SET GLOBAL為以后新建的所有MYSQL連接設(shè)置隔離模式(當(dāng)前連接不包括在內(nèi))
隔離模式
READ UNCOMMITTED不隔離SELECT其他事務(wù)未完成的修改(未COMMIT)饮睬,其結(jié)果也考慮在內(nèi)
READ COMMITTED把其他事務(wù)的 COMMIT 修改考慮在內(nèi)同一個事務(wù)中,同一 SELECT 可能返回不同結(jié)果
REPEATABLE READ(默認)不把其他事務(wù)的修改考慮在內(nèi)篮奄,無論其他事務(wù)是否用COMMIT命令提交過同一個事務(wù)中捆愁,同一 SELECT 返回同一結(jié)果(前提是本事務(wù),不修改)
SERIALIZABLE和REPEATABLE READ類似窟却,給所有的SELECT都加上了 共享鎖
出錯處理根據(jù)出錯信息昼丑,執(zhí)行相應(yīng)的處理
mysql事物處理實例
MYSQL的事務(wù)處理主要有兩種方法1.用begin,rollback,commit來實現(xiàn) begin開始一個事務(wù) rollback事務(wù)回滾 commit 事務(wù)確認2.直接用set來改變mysql的自動提交模式 mysql默認是自動提交的,也就是你提交一個query夸赫,就直接執(zhí)行菩帝!可以通過 set autocommit = 0 禁止自動提交 set autocommit = 1 開啟自動提交 來實現(xiàn)事務(wù)的處理。但要注意當(dāng)用set autocommit = 0 的時候,你以后所有的sql都將作為事務(wù)處理呼奢,直到你用commit確認或 rollback結(jié)束宜雀,注意當(dāng)你結(jié)束這個事務(wù)的同時也開啟了新的事務(wù)!按第一種方法只將當(dāng)前的做為一個事務(wù)!MYSQL只有 INNODB和BDB類型的數(shù)據(jù)表才支持事務(wù)處理握础,其他的類型是不支持的!MYSQL5.0 WINXP下測試通過~ _
代碼如下
復(fù)制代碼

mysql> use test;    Database changed    mysql> CREATE TABLE `dbtest`(    -> id int(4)    -> ) TYPE=INNODB;Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> select * from dbtest -> ;Empty set (0.01 sec)
mysql> begin;Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(5);Query OK, 1 row affected (0.00 sec)
mysql> insert into dbtest value(6);Query OK, 1 row affected (0.00 sec)
mysql> commit;Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;+------+| id |+------+| 5 || 6 |+------+2 rows in set (0.00 sec)
mysql> begin;Query OK, 0 rows affected (0.00 sec)
mysql> insert into dbtest values(7);Query OK, 1 row affected (0.00 sec)
mysql> rollback;Query OK, 0 rows affected (0.00 sec)
mysql> select * from dbtest;+------+| id |+------+| 5 || 6 |+------+2 rows in set (0.00 sec)

mysql> mysql事務(wù)處理
php代碼實現(xiàn)事務(wù)的處理可以通過PHP預(yù)定義類mysqli的以下方法實現(xiàn)辐董。autocommit(boolean):該方法用于限定查詢結(jié)果是否自動提交,如果該方法的參數(shù)為true則自動提交禀综,如果參數(shù)為false則關(guān)閉自動提交简烘。MySQL數(shù)據(jù)庫默認為自動提交。rollback():利用mysqli類中的該方法可以實現(xiàn)事務(wù)的回滾定枷。commit():利用該方法可以實現(xiàn)提交所有查詢孤澎。
代碼如下
復(fù)制代碼

<?phpinclude_once("conn.php");
$id=$_GET[id];$conn->autocommit(false);if(!$conn->query("delete from tb_sco where id='".$id."'")){ $conn->rollback();}if(!$conn->query("delete from tb_stu where id='".$id."'")){ $conn->rollback();} $conn->commit(); $conn->autocommit(true); echo "ok"?>

列二
代碼如下
復(fù)制代碼

<?phprequire('connectDB.php'); //建立數(shù)據(jù)庫連接mssql_query("BEGIN TRANSACTION DEPS02_DEL"); //開始事務(wù)$delete_dep_sql="DELETE FROM TBLDEPARTMENT WHERE DEPTID='{$_GET[deptid]}'";// echo $delete_dep_sql."
";mssql_query($delete_dep_sql); //操作數(shù)據(jù)庫// var_dump($del_result);$delete_result = mssql_query("select @@ROWCOUNT as id");$delete_info = mssql_fetch_array($delete_result);$delete_rows = $delete_info[0];// var_dump($delete_rows);mssql_free_result($delete_result);echo "<script language=javascript>";if(true){ //判斷是否回滾提交mssql_query("COMMIT TRANSACTION DEPS02_DEL"); //提交事務(wù)echo "alert('delete success!');";}else{mssql_query("ROLLBACK TRANSACTION DEPS02_DEL"); //回滾事務(wù)echo "alert('delete faile!');";}echo "</script>";mssql_close();?>

例3
MySQL的事務(wù)處理在處理實際問題中有著廣泛且重要的應(yīng)用,最常見的應(yīng)用如銀行轉(zhuǎn)賬業(yè)務(wù)欠窒、電子商務(wù)支付業(yè)務(wù)等等覆旭。但是,值得注意的是岖妄,MySQL的事務(wù)處理功能在MYSIAM存儲引擎中是不支持的型将,在InnoDB存儲引擎中是支持的。現(xiàn)在上傳一段代碼衣吠,作為引導(dǎo)認識MySQL事務(wù)處理的開始茶敏,簡單的實例壤靶,但融匯思想缚俏,相信會有很大的幫助。
代碼如下
復(fù)制代碼

<?php$conn=mysql_connect('localhost','root','yourpassword')or die(mysql_error());mysql_select_db('transaction',$conn);mysql_query('set names utf8');
//創(chuàng)建事務(wù)mysql_query('START TRANSACTION') or die(mysql_error());$sqlA="update A set account=account-1";if(!mysql_query($sqlA)){ mysql_query('ROLLBACK') or exit(mysql_error());//判斷當(dāng)執(zhí)行失敗時回滾 exit();}$sqlB="update B set account=account+1";if(!mysql_query($sqlB)){ mysql_query('ROLLBACK') or exit(mysql_error());//判斷當(dāng)執(zhí)行失敗時回滾 exit();}mysql_query('COMMIT')or die(mysql_error());//執(zhí)行事務(wù)mysql_close($conn);?>

以上代碼可以作為模擬銀行轉(zhuǎn)賬業(yè)務(wù)的事務(wù)流程贮乳。以表A忧换、B分別表示兩個已在銀行開戶的賬戶,當(dāng)賬戶A執(zhí)行轉(zhuǎn)出1元給賬戶B的操作時向拆,如果操作執(zhí)行失敗亚茬,轉(zhuǎn)出將會回滾至原始狀態(tài),不繼續(xù)向下執(zhí)行動作浓恳。反之刹缝,如果操作執(zhí)行成功,則賬戶B可用余額將增加1元颈将,否則事務(wù)回滾至原始狀態(tài)梢夯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晴圾,隨后出現(xiàn)的幾起案子颂砸,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件人乓,死亡現(xiàn)場離奇詭異勤篮,居然都是意外死亡,警方通過查閱死者的電腦和手機色罚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門碰缔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人保屯,你說我怎么就攤上這事手负。” “怎么了姑尺?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵竟终,是天一觀的道長。 經(jīng)常有香客問我切蟋,道長统捶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任柄粹,我火速辦了婚禮喘鸟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驻右。我一直安慰自己什黑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布堪夭。 她就那樣靜靜地躺著愕把,像睡著了一般。 火紅的嫁衣襯著肌膚如雪森爽。 梳的紋絲不亂的頭發(fā)上恨豁,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機與錄音爬迟,去河邊找鬼橘蜜。 笑死,一個胖子當(dāng)著我的面吹牛付呕,可吹牛的內(nèi)容都是我干的计福。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼徽职,長吁一口氣:“原來是場噩夢啊……” “哼象颖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起活箕,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤力麸,失蹤者是張志新(化名)和其女友劉穎可款,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體克蚂,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡闺鲸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了埃叭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摸恍。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赤屋,靈堂內(nèi)的尸體忽然破棺而出立镶,到底是詐尸還是另有隱情,我是刑警寧澤类早,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布媚媒,位于F島的核電站,受9級特大地震影響涩僻,放射性物質(zhì)發(fā)生泄漏缭召。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一逆日、第九天 我趴在偏房一處隱蔽的房頂上張望嵌巷。 院中可真熱鬧,春花似錦室抽、人聲如沸搪哪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晓折。三九已至,卻和暖如春神年,著一層夾襖步出監(jiān)牢的瞬間已维,已是汗流浹背行嗤。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工已日, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人栅屏。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓飘千,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栈雳。 傳聞我的和親對象是個殘疾皇子护奈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

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