一.简介
所谓事务,是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或者撤销操作请求,即,这些操作要么同时成功,或者同时失败——OS中有原语不可分割的概念,虽然没有必然联系,但此处可以类比~
回滚:临时修改的数据因为发生异常必须修改回去
注意:默认MySQL的数据库是自动提交的,执行一条sql语句,MySQL会立即隐式的提交事务~
二.操作
以转账的场景为例:
select * from account where name='张三';
-- 查询张三余额
update account set money =money-1000 where name ='张三';
--张三余额少了1000
update account set money = money+1000 where name='李四';
--李四余额增加1000
如若发生如下异常:
select * from account where name='张三';
-- 查询张三余额
update account set money =money-1000 where name ='张三';
--张三余额少了1000
强行语法错误报错!
update account set money = money+1000 where name='李四';
--李四余额增加1000
则会导致张三减1000而李四不加1000。
变更事务的提交方式一:
- 查看并设置事务提交方式为0。
select @@autocommit; set @@autocommit=0;
- 提交事务。
commit;
- 回滚事务。
Rollback;
将上述代码修改为如下:
select @@autocommit;
set @@autocommit=0;
select * from account where name='张三';
-- 查询张三余额
update account set money =money-1000 where name ='张三';
--张三余额少了1000
强行语法错误报错!
update account set money = money+1000 where name='李四';
--李四余额增加1000
commit;
Rollback;
则,当发生异常时,数据也不会受到影响~
方法二:不改变事务提交方式
start transaction; select * from account where name='张三'; -- 查询张三余额 update account set money =money-1000 where name ='张三'; --张三余额少了1000 强行语法错误报错! update account set money = money+1000 where name='李四'; --李四余额增加1000 commit; Rollback;
三.四大特性ACID
四.并发事务问题
- 脏读: 通俗地说就是某一个事务中更改了表中的数据,但还没有提交,此时另外一个事务却已经有了查询该表中数据的操作~
- 不可重复读:因为别的事务的干预,导致两次查询结果不一致
- 幻读:由于可重复读读取的永远都是事务刚开始时的数据,因此事务A中两次想要查询结果都为空
五.事务隔离级别
(翻译过来分别为:读未提交,读已提交,可重复读,串行化)~
选择时,要权衡数据的安全性和并发的性能~
select @@transaction_isolation;
--查询当前事务隔离级别
set [session|global] transaction isolation level
{read uncommitted|read committed|repeatable read|serializable};
--改变事务隔离级别
- 单个竖杠表示可选一
- session表示只作用对话窗,global表示作用于全局~