事務mysql
事務實際上是一組對數據庫增刪改操做的組合,能夠這樣來理解,當你往某我的身上打1000元的時候,在數據庫中會發生兩個改變,一個是你的錢減小了,另外一個是那我的的錢增長了,這兩個操做必須同時知足,否則問題就大了,怎樣保證兩個操做所有執行,這就須要mysql事務的支持。sql
mysql是支持事務的,但首先確認你是InnoDB存儲引擎數據庫
mysql事務是爲了維護數據庫的完整性,堆成批量的語句要麼所有執行,要麼所有不執行。通常用來管理insert delete 和update語句的。
服務器
事務的特色:ide
一、事務的原子性:一組事務,要麼成功;要麼撤回。學習
二、穩定性 : 有非法數據(外鍵約束之類),事務撤回。測試
三、隔離性:事務獨立運行。一個事務處理後的結果,影響了其餘事務,那麼其餘事務會撤回。事務的100%隔離,須要犧牲速度。spa
四、可靠性:軟、硬件崩潰後,InnoDB數據表驅動會利用日誌文件重構修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit選項 決定何時吧事務保存到日誌裏。3d
下面是在mysql中操做的一些命令;日誌
set autoaction=0;//這條命令用來取消mysql的自動提交。 begin;//事務開始。 savepoint pointname;//設立存儲點,設立多個可使用rollback返回到某一個上。 rollback pointname;//返回到某個point。 rollback;//不使用point則返回到begin。 commit;//若是能夠提交則用commit提交。
使用 show variables like 'autocommit';能夠查看當前autoaction的狀態
下面是我在mysql下執行的測試:
能夠看出使用rollback後退回到了添加以前的數據。
使用savepoint的方式,讀者能夠下去測試。
下面是C語言下對事務的測試:(使用connect c包)
首先測試前表中的數據時這樣的
個人測試代碼以下:
這裏的my_sql.h只給出了關於事務這部分的代碼(關於數據庫的全部操做的代碼會在後面的手動搭建 http服務器的博客中給出)。
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後面少了一個等於號 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);//由於str2必定會執行失敗索引返回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 //執行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%
測試結果
顯然表中沒有發生改變。
更改代碼將上面的'='加上結果以下
在使用各類語言對事務進行操做的時候要在最後手動關閉鏈接 mysql_close();
你覺得上面的就正確了嗎?確實是正確的,由於上面的都是已經配置好的。
在沒有弄好以前,花了測試了很久,才發現一個大坑!!聽我慢慢道來:
查閱了相關資料,基本上都是在用show engines;查看是否支持innodb存儲引擎,可是測試以後卻發現根本rollback不了,在代碼中顯示的是success,但數據庫中倒是1 worning; 雖然show engines顯示的 innodb是yes,但你仍須要添加這段代碼:
alter table test_info type=INNODB;否則你有可能永遠都測試成功不了。
總結:事務對數據庫的完整性具備很深的意義。是不可或缺的一部分。關於事務的使用還有不少方面。須要慢慢學習