
MySQL教程(7)MySQL事务特性与隔离级别
一、MySQL事务介绍
1、MySQL事务特性
MySQL事务有4大特性,分别是原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability),简称ACID。在这4个特性中,原子性是基础,隔离性是手段,一致性是约束条件,而持久性是最终目的
· 原子性(atomicity):原子是不可再切分的,所以事务的原子性是指事务开始后的所有操作要么全部执行,要么全部不执行,不应该有部分执行的情况存在。常见的场景就是银行转账,如果A要给B转账1000元,那么A账户减少1000与B账户增加1000这两个操作需要放在一个事务中完成。如果事务在执行过程中出错(包含会话断开、服务宕机)会由undo log(记录数据修改前的状态)回滚到事务开始前的状态
· 一致性(consistency):事务执行前后需要从一个状态变到另一个状态,但是这个状态需要符合业务的约束。比如A向B转账1000,不应存在A扣除1000后而B没有增加的情况;又比如A账户有1000,但是不能给B账户转账2000。由redo log(记录数据修改后的状态)来保持一致性。可以说原子性、隔离性、持久性都是为了保障一致性而存在的,一致性也是最终目的
· 隔离性(isolation):一个事务的执行不能被其他事务干扰,也就是说同一个时间内只允许一个事务对同一个数据进行处理
· 持久性(durability):事务完成后数据应该落盘,能够用久保存,并且不能再rollback回滚
2、MySQL事务控制
· 显式开启事务
如果显式开启了事务,一定要注意及时关闭,避免长事务问题
# 使用begin语句开启事务,然后commit语句提交事务 begin; 加入事务中的语句; commit; # 使用start transaction开启事务,相比begin可以增加修饰符,默认为read write以及snapshot start transaction [read write]/[read write] with consistent snapshot;
· 自动提交事务
当数据库设置autocommit=1时(默认为1),每一个DML都是一个事务,即便没有加begin语句开启事务,数据库也会自动开启事务并进行commit
· 隐式开启事务
对于DDL语句来说,它们都是单独的事务。如果DML中加有DDL会触发隐式提交,事务不支持嵌套,所以在一个事务中再开启事务也会导致前一个事务被提交
#rollback回滚事务 rollback #回滚所有未提交的事务 rollback to s1 #回滚到S1这个保存点(savepoint)
二、MySQL隔离级别
1、脏读、不可重复度与幻读
· 脏读:在事务1中查询到的数据是事务2已经修改过但未提交的,一旦事务2发生回滚,那事务1获取到的数据就是无效的
· 不可重复度:在一个事务中对数据进行多次查询,得到的结果因为数据被其它事务所修改而不一致
· 幻读:在一个事务中对数据进行多次查询,但是后续的查询读取到了之前没有的记录,也就是发生了新增数据(如果是删除了数据属于不可重复读的范围)。比如事务1对年龄<30的数据进行修改,事务2在事务1提交之前又新增了一个<30的数据,这个时候事务1提交之后会看到依然有一个<30的数据存在,带来修改失败的幻觉
2、MySQL事务隔离级别
· 未提交读(read uncommitted):最低的隔离级别,在一个事务中可以读取到另一个事务已修改但尚未提交的结果。该隔离级别容易造成脏读、不可重复读、幻读,所以不建议使用。为了避免脏读、不可重复读、幻读导致主从数据不一致,当前隔离级别下binlog格式不能为statement
· 已提交读(read commited):只有事务提交后其更新结果才可以被其他事务查询。Oracle、SQL Server等大多数数据库系统的默认隔离级别(但MySQL并不是)。该隔离级别解决了RU级别的脏读问题,但存在不可重复读和幻读情况(同样的查询语句,在每一次进行查询的时候都会重新获取read view,所以产生不可重复读或者幻读)。为了避免脏读、不可重复读、幻读导致主从数据不一致,当前隔离级别下binlog格式不能为statement。该隔离级别下由于不存在GAP锁,所以性能会更好,也是最推荐使用的,如果在数据一致性高的场景,可以通过代码层进行会话级别的隔离级别设置
· 可重复读(repeatable read):Innodb引擎的默认隔离级别。在同一个事务中,如果对某行数据进行多次查询,其查询结果通过MVCC快照读的方式保证永远是相同的(快照读的样本是在SELECT那刻自动创建),即便事务2已经修改了数据并提交,但是在事务1中依然不会有变化。该隔离级别解决了脏读、不可重复读以及大部分幻读的发生。该隔离级别可以通过GAP锁解决幻读问题,但是对并发性能有一定影响,所以通常不太推荐使用该隔离级别,而是保持使用RC,至于幻读问题就需要忽略或者用其他手段解决
· 串行化(serializable):事务串行化处理,不会出现脏读、幻读、不可重复读的问题,隔离级别最高,但会导致大量的锁超时和锁竞争问题,因此性能最差,也不建议使用
PS:四个隔离级别逐个解决脏读、不可重复读、幻读的问题,但是随着隔离级别的上升,事务请求的锁和锁的时间就会越长。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
Read Uncommitted | 是 | 是 | 是 |
Read Committed | 否 | 是 | 是 |
Repeatable Read | 否 | 否 | 是 |
Serializable | 否 | 否 | 否 |
3、MySQL事务隔离级别的设置
#查看事务隔离级别 show global variables like 'tx_isolation'; #在线设置事务隔离级别 set global tx_isolation='READ-COMMITTED' #永久生效 vi /etc/my.cnf tx_isolation=READ-COMMITTED'
猜你喜欢

MySQL MySQL教程(6)MySQL索引与执行计划
一、MySQL索引1、索引分类MySQL官方对索引的定义是"帮助MySQL高效获取数据的数据结构",通俗来讲索引相当于字典的音序表或书籍的目录,通过将索引包含的字段进行排序(默认升...

PostgreSQL PostgreSQL教程(4)对象的基本管理
一、PostgreSQL 对象介绍对象指的是在 PostgreSQL 数据库实例中可以被创建、管理和操作的各类实体或结构。包含数据库、表、索引、视图、序列、函数、触发器等,这些不同的对象构成了完整的数...

PostgreSQL PostgreSQL教程(3)数据库常用参数与配置方法
一、PostgreSQL 配置文件介绍在PGSQL中如果要对参数进行修改,可以通过修改静态参数文件(postgresql.conf)、动态参数文件(postgresql.auto.conf)与自定义参...

PostgreSQL PostgreSQL教程(2)客户端工具psql的使用
一、命令行客户端psql 是 PostgreSQL 的命令行客户端工具,类似于MySQL中的mysql、Oracle中的sqlplus。通过psql可以实现对 PostgreSQL 数据库的...

MySQL MySQL教程(5)多表连接查询与子查询
一、MySQL 多表连接查询多表连接查询是指在多个表中,存在一个或多个相同的字段(这些字段的值必须一致),通过将这些字段连接起来,就能将不同表的数据整合在一起,形成一张包含所有相关信息的大表。这样就可...
文章评论