事务
事务其实是一组对数据库增删改操作的组合,可以这样来理解,当你往某个人身上打1000元的时候,在数据库中会发生两个改变,一个是你的钱减少了,另一个是那个人的钱增加了,这两个操作必须同时满足,不然问题就大了,怎样保证两个操作全部执行,这就需要mysql事务的支持。
mysql是支持事务的,但首先确认你是InnoDB存储引擎
mysql事务是为了维护数据库的完整性,堆成批量的语句要么全部执行,要么全部不执行。一般用来管理insert delete 和update语句的。
事务的特点:
1、事务的原子性:一组事务,要么成功;要么撤回。
2、稳定性 : 有非法数据(外键约束之类),事务撤回。
3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。
下面是在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;不然你有可能永远都测试成功不了。
总结:事务对数据库的完整性具有很深的意义。是不可或缺的一部分。关于事务的使用还有很多方面。需要慢慢学习
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。