淺談數據庫--事務(mysql)

事務mysql


  事務實際上是一組對數據庫增刪改操做的組合,能夠這樣來理解,當你往某我的身上打1000元的時候,在數據庫中會發生兩個改變,一個是你的錢減小了,另外一個是那我的的錢增長了,這兩個操做必須同時知足,否則問題就大了,怎樣保證兩個操做所有執行,這就須要mysql事務的支持。sql


mysql是支持事務的,但首先確認你是InnoDB存儲引擎數據庫

wKiom1dnyT_j-W02AACX2WhXRAY777.png


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下執行的測試:

wKioL1dn_dejDdw2AAC9cXdAiHU470.png

wKiom1dn_iOS3gguAACTSXRQPIM690.png

能夠看出使用rollback後退回到了添加以前的數據。


使用savepoint的方式,讀者能夠下去測試。



下面是C語言下對事務的測試:(使用connect c包)


首先測試前表中的數據時這樣的

wKioL1dn_wyDe4hQAAA3BOerXwA166.png


個人測試代碼以下:


這裏的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%

測試結果

wKioL1dn_wyDe4hQAAA3BOerXwA166.png

顯然表中沒有發生改變。


更改代碼將上面的'='加上結果以下

wKioL1doBEzDtUaaAAAvmL2tgZk514.png


在使用各類語言對事務進行操做的時候要在最後手動關閉鏈接 mysql_close();




你覺得上面的就正確了嗎?確實是正確的,由於上面的都是已經配置好的。


在沒有弄好以前,花了測試了很久,才發現一個大坑!!聽我慢慢道來


查閱了相關資料,基本上都是在用show engines;查看是否支持innodb存儲引擎,可是測試以後卻發現根本rollback不了,在代碼中顯示的是success,但數據庫中倒是1 worning; 雖然show engines顯示的 innodb是yes,但你仍須要添加這段代碼:

alter table test_info type=INNODB;否則你有可能永遠都測試成功不了



總結:事務對數據庫的完整性具備很深的意義。是不可或缺的一部分。關於事務的使用還有不少方面。須要慢慢學習

相關文章
相關標籤/搜索