[toc]
mysql事务隔离级别
mysql事务
一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- **原子性:**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- **一致性:**在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- **隔离性:**数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- **持久性:**事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
mysql 4种事务隔离级别
级别 | symbol | 对应值 | 含义 | 存在问题 |
---|---|---|---|---|
读未提交 | READ-UNCOMMITTED | 0 | 一个事务可以读到另一个事务未提交的数据 | 存在脏读、不可重复读、幻读的问题 |
读已提交 | READ-COMMITTED | 1 | 一个事务能读到另一个事务已提交的数据 | 解决脏读的问题,存在不可重复读、幻读的问题 |
可重复读 | REPEATABLE-READ | 2 | 同一事务的多个实例在并发读取数据时,会看到同样的数据行 | mysql默认级别,解决脏读、不可重复读的问题,存在幻读的问题。使用 MMVC机制 实现可重复读 |
串行化 | SERIALIZABLE | 3 | 强制事务排序,使之不可能相互冲突 | 解决脏读、不可重复读、幻读,可保证事务安全,但完全串行执行,性能最低 |
关于mysql事务的一些知识点
- 最开始的时候,5.1.5之前的版本binlog format只支持stament,并没有row模式,在RC一些场景下会造成主从数据不一致,所以选择RR才能最大限度保证主从数据一致性
- 之后的mysql直接使用RC+row是完全没有问题的
mysql5.7表的默认存储引擎是InnoDB
mysql> show create table t1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(3) NOT NULL,
`name` char(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)
mysql5.7 InnoDB存储引擎默认的事务隔离级别,全局和当前会话都是REPEATABLE-READ(可重复读)
RR的并发性没有RC好
#mysql5.7.22
mysql> SELECT @@global.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)
设置事务隔离级别
#配置文件修改,可选参数 READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、 SERIALIZABLE
[mysqld]
transaction-isolation = REPEATABLE-READ
#设置全局
SET @@global.tx_isolation = 0;
SET @@global.tx_isolation = 'READ-UNCOMMITTED';
SET @@global.tx_isolation = 1;
SET @@global.tx_isolation = 'READ-COMMITTED';
SET @@global.tx_isolation = 2;
SET @@global.tx_isolation = 'REPEATABLE-READ';
SET @@global.tx_isolation = 3;
SET @@global.tx_isolation = 'SERIALIZABLE';
#设置会话
SET @@session.tx_isolation = 0;
SET @@session.tx_isolation = 'READ-UNCOMMITTED';
SET @@session.tx_isolation = 1;
SET @@session.tx_isolation = 'READ-COMMITTED';
SET @@session.tx_isolation = 2;
SET @@session.tx_isolation = 'REPEATABLE-READ';
SET @@session.tx_isolation = 3;
SET @@session.tx_isolation = 'SERIALIZABLE';
mysql查看/设置自动提交
//查看自动提交是否开启,默认开启
#方法一
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.07 sec)
#方法二
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.09 sec)
//关闭自动提交
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.11 sec)
以下所有示例都基于mysql5.7.22
先创建一张示例表t1
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.22 |
+-----------+
mysql> create table t1(id int(3) primary key,name char(30));
mysql> insert into t1 values(1,'xiaoming');
mysql> select * from t1;
+----+----------+
| id | name |
+----+----------+
| 1 | xiaoming |
+----+----------+