目录
1、什么是事务
mysql数据库事务:(database transaction):事务是一组sql语句组成的逻辑处理单元,这些操作要么全做要么全不做,是一个不可分割的工作单位。
mysql中只有innodb和bdb类型的数据表才能支持事务处理!其他的类型不支持!
数据库默认事务时自动提交的,也就是发一条sql 它就执行一条。如果想多条sql放在一个事务中执行,则需要使用事务进行处理。当我们开启事务,并且没有提交,mysql会自动回滚事务,或者我们使用rollback命令手动回滚事务。
2、为什么使用事务:
通过将一组操作组成一个操作单元,执行时,要么全部成功,要么全部失败的单元。
例如:A账户汇款给B账户1000元。
A账户-1000
B账户+1000
以上操作对应数据库为两个update。这两个操作属于一个事务。否则可能会出现A账户钱少了,B账户钱没有增加的情况;或者因为A账户的余额不足(少于1000),而B账户却增加1000。
3、事务的四大特性:
事务必须满足4个条件(ACID)
原子性(Autmic):事务必须是原子工作单元,不能被分割的,事务中的操作要么全部执行,要么全部不执行,不能只完成部分操作。
一致性(Consistency):事务开始之前,数据库处于一致性的状态;事务结束后,数据库必须仍处于一致性状态。数据库一致性的定义是由用户负责的。例如在银行转账中,用户可以定义转账前后两个账户金额之和保持不变。
隔离性(Isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的其他事务是隔离的,并发执行的各个事务之间不能相互干扰,这些通过锁来实现。
持久性(Durability:指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
事务的ACID原则保证了一个事务或者成功提交,或者失败回滚,两者必居其一。因此事务对数据的修改具有可回复性,即当事务失败时,它对数据的修改都会回复到该事务执行前的状态。
4、MySQL事务处理的方法
用begin或start transaction,rollback,commit来实现事务
start transaction | begin #开启事务
commit #提交当前事务,执行永久操作。
rollback #回滚当前事务到开始点,取消上一次开始点后的所有操作。
MySQL默认是自动提交的,也就是你提交一个sql query,它就直接执行!
set autocommit={0|1} 设置事务是否自动提交,默认是自动提交的。
0:禁止自动提交
1:开启自动提交
注意:MySQL中只有innodb和bdb类型的数据表才能支持事务处理!其他的类型不支持!
修改数据库引擎为innodb
alter table books engine=innodb;
alter table category engine=innodb;
例:
用到的表:
desc books;
set autocommit=0;
delimiter //
start transaction;
update books set bName="ccc" where bId=1;
update books set bName="ddd" where bId=2;
commit;//
delimiter ;
select bName from books where bId=1 or bId=2;
可以看到修改bId为1和bId为2的数据中的bName成功被分别修改为ccc,ddd。
回滚刚刚执行的事务:roll back
再来查看结果:
select bName from books where bId=1 or bId=2;
回滚失败,因为我们commit已经成功提交了。
再重新做一次实验不提交:
delimiter //
start transaction;
update books set bName="AH" where bId=1;
update books set bName="AL" where bId=2;
// #不提交
delimiter ;
查看事务执行结果:
select bName from books where bId=1 or bId=2;
事务执行成功,数据更改成功。
执行回滚操作:
rollback;
再来查看事务执行结果,发现数据回滚到了事务开始前的状态。
select bName from books where bId=1 or bId=2;
很多时候一个事务会包含多条语句,而出现问题需要回滚时,并不一定是要回滚到begin之前的状态,有可能是某条语句执行后的状态,这时要使用savepoint定义回滚点,rollback决定回滚到的位置。
下面举例说明:
desc stu;
关闭MySQL的自动提交功能:set autocommit=0;
begin;
insert into str values(1,'berry');
savepoint s1;
insert into stu values(2,'linda');
savepoint s2;
执行第一条插入语句后,定义了回滚点s1,执行第二条插入语句后,定义了回滚点s2,如果后面直接使用rollback命令,这两条插入语句都将直接失效,现在使用回滚点进行回滚。
执行回滚钱,查询stu表中数据:
select * from stu;
执行rollback回滚到s1回滚点
rollback to savepoint s1;
select * from stu;
回滚到了s1,第一条插入的数据可以查询出来,但是并没有提交,如果需要保存到数据库,使用commit命令提交。