[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之后,才会将事务中的操作应用到数据库。