您好,登錄后才能下訂單哦!
事務(wù)
事務(wù)其實(shí)是一組對(duì)數(shù)據(jù)庫增刪改操作的組合,可以這樣來理解,當(dāng)你往某個(gè)人身上打1000元的時(shí)候,在數(shù)據(jù)庫中會(huì)發(fā)生兩個(gè)改變,一個(gè)是你的錢減少了,另一個(gè)是那個(gè)人的錢增加了,這兩個(gè)操作必須同時(shí)滿足,不然問題就大了,怎樣保證兩個(gè)操作全部執(zhí)行,這就需要mysql事務(wù)的支持。
mysql是支持事務(wù)的,但首先確認(rèn)你是InnoDB存儲(chǔ)引擎
mysql事務(wù)是為了維護(hù)數(shù)據(jù)庫的完整性,堆成批量的語句要么全部執(zhí)行,要么全部不執(zhí)行。一般用來管理insert delete 和update語句的。
事務(wù)的特點(diǎn):
1、事務(wù)的原子性:一組事務(wù),要么成功;要么撤回。
2、穩(wěn)定性 : 有非法數(shù)據(jù)(外鍵約束之類),事務(wù)撤回。
3、隔離性:事務(wù)獨(dú)立運(yùn)行。一個(gè)事務(wù)處理后的結(jié)果,影響了其他事務(wù),那么其他事務(wù)會(huì)撤回。事務(wù)的100%隔離,需要犧牲速度。
4、可靠性:軟、硬件崩潰后,InnoDB數(shù)據(jù)表驅(qū)動(dòng)會(huì)利用日志文件重構(gòu)修改??煽啃院透咚俣炔豢杉娴?, innodb_flush_log_at_trx_commit選項(xiàng) 決定什么時(shí)候吧事務(wù)保存到日志里。
下面是在mysql中操作的一些命令;
set autoaction=0;//這條命令用來取消mysql的自動(dòng)提交。 begin;//事務(wù)開始。 savepoint pointname;//設(shè)立存儲(chǔ)點(diǎn),設(shè)立多個(gè)可以使用rollback返回到某一個(gè)上。 rollback pointname;//返回到某個(gè)point。 rollback;//不使用point則返回到begin。 commit;//如果可以提交則用commit提交。
使用 show variables like 'autocommit';可以查看當(dāng)前autoaction的狀態(tài)
下面是我在mysql下執(zhí)行的測(cè)試:
可以看出使用rollback后退回到了添加之前的數(shù)據(jù)。
使用savepoint的方式,讀者可以下去測(cè)試。
下面是C語言下對(duì)事務(wù)的測(cè)試:(使用connect c包)
首先測(cè)試前表中的數(shù)據(jù)時(shí)這樣的
我的測(cè)試代碼如下:
這里的my_sql.h只給出了關(guān)于事務(wù)這部分的代碼(關(guān)于數(shù)據(jù)庫的所有操作的代碼會(huì)在后面的手動(dòng)搭建 http服務(wù)器的博客中給出)。
my_sql.h 13 } 14 bool HttpSql::mysql_start() 15 { 16 if(mysql_query(mysql,"SET autocommit=0")==0) 17 { 18 cout<<"start success"<<endl; 19 return true; 20 } 21 else { 22 return false; 23 } 24 25 } 26 bool HttpSql::mysql_begin() 27 { 28 if(mysql_query(mysql,"BEGIN")==0) 29 { 30 cout<<"begin success"<<endl; 31 return true; 32 } 33 else{ 34 return false; 35 } 36 } 37 bool HttpSql::mysql_commit() 38 { 39 if(mysql_query(mysql,"COMMIT")==0) 40 { 41 cout<<"commit success"<<endl; 42 return true; 43 } 44 else{ 40 { 41 cout<<"commit success"<<endl; 42 return true; 43 } 44 else{ 45 return false; 46 } 47 } 48 bool HttpSql::mysql_rollback() 49 { 50 if(mysql_query(mysql,"ROLLBACK")==0) 51 { 52 cout<<"rollback success"<<endl; 53 return true; 54 } 55 else 56 { 57 return false; 58 } 59 } 121 bool HttpSql::mysql_modify(string str) 122 { 123 bool ret=false; 124 string _str="update test_info set "; 125 // cout<<str<<endl; 126 _str+=str.c_str(); 127 // cout<<_str<<endl; 128 ret=mysql_op(_str); 129 if(ret) 130 { 131 return 1; 132 }else{ 133 return -1; 134 } 135 } 46,3-9 28% 32,2-8 8%
modify.cpp #include"my_sql.h" 104 int main() 105 { 106 HttpSql sql; 107 if(!sql.mysql_start()) 108 { 109 return -1; 110 } 111 char buf1[1024]; 112 char buf2[1024]; 113 memset(buf1,'\0',sizeof(buf1)); 114 memset(buf2,'\0',sizeof(buf2)); 115 strcpy(buf1,"update test_info set name=\"wangmazi\" where name=\"zhangsan\""); 116 strcpy(buf2,"update test_info set name=\"wangmazi\" where name\"lisi\""); //上面這行代碼我故意在where name后面少了一個(gè)等于號(hào) 117 string str1(buf1); 118 string str2(buf2); 119 if(!sql.mysql_begin()) 120 { 121 return -1; 122 } 123 int ret1=sql.mysql_op(str1); 124 int ret2=sql.mysql_op(str2);//因?yàn)閟tr2一定會(huì)執(zhí)行失敗索引返回false. 125 //ret1=false; 126 if(ret1&&ret2) 127 { 128 if(sql.mysql_commit()) 129 { 130 cout<<"modify success"<<endl; 131 } 132 else{ 133 cout<<"modify failure"<<endl; 134 } 135 }else //執(zhí)行else語句使其退回修改之前的樣子。 136 { 137 if(sql.mysql_rollback()) 138 { 139 cout<<"modify failure roolback success"<<endl; 140 } 141 else{ 142 cout<<"boom!!!1"<<endl; 143 } 144 } 145 146 147 } 131,2-8 底端 116,2-5 89%
測(cè)試結(jié)果
顯然表中沒有發(fā)生改變。
更改代碼將上面的'='加上結(jié)果如下
在使用各種語言對(duì)事務(wù)進(jìn)行操作的時(shí)候要在最后手動(dòng)關(guān)閉連接 mysql_close();
你以為上面的就正確了嗎?確實(shí)是正確的,因?yàn)樯厦娴亩际且呀?jīng)配置好的。
在沒有弄好之前,花了測(cè)試了好久,才發(fā)現(xiàn)一個(gè)大坑!!聽我慢慢道來:
查閱了相關(guān)資料,基本上都是在用show engines;查看是否支持innodb存儲(chǔ)引擎,但是測(cè)試之后卻發(fā)現(xiàn)根本rollback不了,在代碼中顯示的是success,但數(shù)據(jù)庫中卻是1 worning; 雖然show engines顯示的 innodb是yes,但你仍需要添加這段代碼:
alter table test_info type=INNODB;不然你有可能永遠(yuǎn)都測(cè)試成功不了。
總結(jié):事務(wù)對(duì)數(shù)據(jù)庫的完整性具有很深的意義。是不可或缺的一部分。關(guān)于事務(wù)的使用還有很多方面。需要慢慢學(xué)習(xí)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。