最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

MySQL之事务和事务隔离级别

XAMPP案例 admin 455浏览 0评论
不知道大家有没有想过这样一个问题,就是银行转账的时候,如果银行ATM的系统崩了(超低概率事件…),钱已经转了,这个时候会不会出现对方没收到转账但是我的钱也没了的情况呢?钱可是敏感话题,只要涉及到钱的问题,肯定不会这么草率,既然不会丢,又是如何保证系统崩了或者网络断开这种情况下数据的一致呢?就是我们今天介绍的事务。
 01mysql
事务简介
首先来看是什么事务,事务是伴随着交易类的业务场景出现的工作机制,简单来讲一个事务可以包含多条SQL语句,这些SQL语句要么同时执行成功要么都不会成功。事务的作用就是保证数据的安全,防止在操作多条数据的时候可能会出现某几条数据操作不成功的情况。
 
事务的特性
事务为了保证数据的安全,有下述特性,称为ACID:Automic:原子性,在一个事务单元中(从开启事务到事务提交),所有标准事务语句(DML)要么全成功,要么全回滚(回到事务提交之前的状态);Consistency:一致性,事务发生前、发生中、发生后都应该始终保持数据一致;

Isolatin:隔离性,MySQL支持多事务并发工作,某个事务工作的时候不能受到其他事务的影响;

Durability:持久性,当事务提交成功之后,此次事务操作的所有数据都需要永久保存。

 

事务生命周期管理
标准的事务语句就是DML数据库操作语言,包括insert update delete语句,事务的完整生命周期请看下述SQL:

-- 开启事务
begin/start transaction;

-- 对数据库的DML操作
insert...
update...
delete...

-- 事务提交
commit;

-- 事务回滚;
rollback;

比如在MySQL中模拟转账的操作。

create table user(
 id int primary key auto_increment,
 name char(16),
 balance int
);

insert into user(name,balance) values('python',100),('java',100);

-- 先开启事务
start transaction;
-- 书写事务的多条sql语句
update user set balance=900 where name='python';
update user set balance=1010 where name='java';
-- 回滚
rollback;
-- 确认事务
commit;

在执行DML语句的时候会自动在DML语句之前加一个begin,结束会自动加commit,但是在交易类的场景下自动提交事务是不安全的,可以通过修改MySQL的参数将DML语句设置为不自动提交。

-- 如果在autocommit=1的时候没有加begin(没有显式的开启事务),在执行dml语句的时候会自动在这个dml语句自动之前加一个begin,结束会自动加commit;
select @@autocommit;

-- 临时生效:DML语句不自动提交
set global autocommit=0;

-- 永久生效,需要修改mysql的配置文件,需要重启mysql服务
vim /etc/my.conf
[mysqld]
autocommit = 0

当事务非正常关闭时,比如数据库宕机了、事务语句执行失败,这种情况下就会触发隐式回滚。

事务隔离级别
mysql支持多事务并发,多事务并发就需要保证每个事务之间是隔离的,某一个事务的执行不能受到其他事务的影响,事务的隔离分为读未提交、读已提交、不可重复读和串行化,MySQL5.7版本模式的隔离级别是不可重复读。可以通过下述SQL语句查看默认的隔离级别和修改隔离级别:

select @@transaction_isolation; -- 查看默认的隔离级别
set global transaction_isolation='read_uncommited';  -- 参数修改,是临时的,只在当前会话有效

在详细介绍隔离级别之前,需要先了解几个概念:

脏读、幻读、不可重复读
脏读:另一个事务读取了当前事务正在修改并没有提交的数据,违背了事务的隔离性。对于脏读在生产业务中是一般不会允许的。幻读:在一个事务窗口中更新操作没有完成或者没有提交的情况下,出现了别的事务插入的数据。不可重复读:在同一个事务单元中不同时刻进行同样的操作读到了其他事务修改的数据,简单来说就是同一个事务单元不同时刻读到的数据不一致。对于事务隔离性和数据最终一致性要求比较高的业务是不允许出现的。

 

知道了上述的几个概念之后,再来讨论事务的隔离级别,事务的隔离级别有下述四个级别:
事务隔离的四个级别
RU(read uncommited)读未提交:出现的问题:脏读,不可重复读, 幻读RC(read commited)读已提交:出现的问题:不可重复读, 幻读RR(repeatable read)可重复读,默认级别:出现的问题:可能会出现 幻读,但是可以通过其他的机制防止幻读。通过RR,已经可以解决99%的幻读。

SR(serializable….)可串行化:出现的问题:以上问题都可以避免,但是不利于事务的并发

转载请注明:XAMPP中文组官网 » MySQL之事务和事务隔离级别

您必须 登录 才能发表评论!