[mysql基础文档]-23-数据库事务

引言

"MySQL事务"是一个过程,具有隔离性,原子性,一致性,持久性;通俗的讲,所有在"MySQL事务"过程中的操作在提交之前,都没有被真实的写入数据库,类似于数据库的一个"沙盒"。

文章目录

0×1.MySQL事务简介

所有对数据库的修改在"沙盒"过程中是不会影响到真实数据的,只有使用commit命令提交后,这个沙盒过程中对数据库的修改才会真正被写入数据库;

MySQL事务具有以下特性:

原子性(Atomic):一个事务包含多个操作,这些操作要么全部执行,要么全都不执行,这取决于最后会不会执行commit命令;
一致性(Consistency):一致性是指事务使得系统从一个一致的状态转换到另一个一致状态;
隔离性(Isolation):并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据;
持久性(Durability):事务提交后,对系统的影响是永久的;

下面给出一个简单实例,让大家能更好的理解这些理论。

0×2.MySQL事务实例

只有InnoDB引擎才支持事务,请看下面的实例:

					--创建一个表bank,声明两个int字段,默认值都是0,现在假设当前连接到数据库的这个窗口是银行柜台工作人员,在这个银行中有两个账户,分别是A_money和B_money
					mysql> create table bank(A_money int not null default 0,B_money int not null default 0) engine=Innodb;

					--此时,A来到银行,存了5000元到自己的账户,并且他想给B汇款1000元
					mysql> #银行窗口
					mysql> insert into bank(A_money) values(5000);

					--在没有汇款前,两个账户的资金是这样的
					mysql> select * from bank;
					+---------+---------+
					| A_money | B_money |
					+---------+---------+
					|    5000 |       0 |
					+---------+---------+

					--如果此时银行窗口不使用事务,直接给A账户减去1000,给B账户加上1000
					mysql> #银行窗口
					mysql> update bank set A_money=A_money-1000;
					mysql> update bank set B_money=B_money+1000;

					--在操作之后,打开另一个终端并且连上这个数据库,假设这个终端就是B使用的自动取款机终端
					www@qingsword.com:~$ mysql -u root -p
					Enter password: 
					mysql> use qingsword_com;

					mysql> #自动取款机终端
					--在这个终端中查看bank表数据,钱已经打过来了,此时B立刻可以取走这笔钱
					mysql> select * from bank;
					+---------+---------+
					| A_money | B_money |
					+---------+---------+
					|    4000 |    1000 |
					+---------+---------+

					--当B取走这笔钱之后,在银行柜台前准备签字确认汇款的A说"对不起,我想取消这次汇款",就这样,银行损失1000元;当然,这只是个故事,下面让我们用事务来进行一次上面的操作

					--这次的银行是bank6,同样两个账户
					mysql> create table bank6(A_money int not null default 0,B_money int not null default 0);

					--A来到银行,存了5000元到自己的账户,并且他想给B汇款1000元
					mysql> #银行窗口
					mysql> insert into bank6(A_money) values(5000);

					--bank6因为很6,所以吸取了bank的教训,启用了事务过程
					mysql> #银行窗口
					mysql> start transaction; --启用事务

					mysql> update bank6 set A_money=A_money-1000;
					mysql> update bank6 set B_money=B_money+1000;

					--在事务过程中的所有修改并没有真正写入数据库,这个时候,银行柜台给A看了这个结果,并且告诉他,你可以签字确定汇款了
					mysql> select * from bank6;
					+---------+---------+
					| A_money | B_money |
					+---------+---------+
					|    4000 |    1000 |
					+---------+---------+

					--新打开一个终端,模拟此时站在自动取款机前的B
					www@qingsword.com:~$ mysql -u root -p
					Enter password: 
					mysql> use qingsword_com;

					mysql> #自动取款机终端
					--这个新终端中select的结果是这样的,并没有改变
					mysql> select * from bank6;
					+---------+---------+
					| A_money | B_money |
					+---------+---------+
					|    5000 |       0 |
					+---------+---------+

					--这个时候A以为大功告成,放弃签字确认,他说"我想取消汇款",柜台工作人员微微一笑,输入了rollback命令,rollback命令可以让对数据库的修改回到"start transaction;"这条命令之前的状态,所有"start transaction;"之后的操作都不会被写入数据库
					mysql> #银行窗口
					mysql>rollback;
					mysql> select * from bank6;
					+---------+---------+
					| A_money | B_money |
					+---------+---------+
					|    5000 |       0 |
					+---------+---------+

					--只有当输入了下面的命令,提交事务,事务中所有的操作才会被写入数据库,也就是说A如果签字确认汇款,此时可以输入这条命令,与此同时"自动取款机终端"再次select时,就会发现B_money增加了1000。
					mysql> commit;
					

事务过程总结:

					--开始事务过程
					mysql> start transaction;
					--对数据的修改操作
					--事务过程终止,对数据库的所有操作退回事务开始之前的状态
					mysql> rollback;

					--开始事务过程
					mysql> start transaction;
					--对数据的修改操作
					--事务过程终止,对数据库的所有操作全部写入数据库
					mysql> commit;
					

P.s:利用事务的好处是,当事务中出现严重的数据库操作失误的时候,可以使用rollback回到事务启动前状态,只有当使用commit之后,才会将事务中的操作应用到数据库。