事务的隔离级别研究的是各自操作对其他事务是否有影响。
常见的事务隔离级别有四种,分别是读未提交、读已提交、可重复读和串行化。
- 读未提交(Read Uncommitted)在该隔离级别下,一个事务可以读取另一个事务还未提交的数据,可能会发生脏读(Dirty Read)问题。因为其他事务对数据的修改可以立即对本事务可见,而且可能会被回滚,这种级别的隔离性非常低。
- 读已提交(Read Committed)在该隔离级别下,一个事务只能读取已经提交的数据,不能读取其他事务还未提交的数据,可以避免脏读的问题。但是由于其他事务对数据进行的修改,需要等到其提交之后才能对本事务可见,因此可能会出现不可重复读(Non-repeatable Read)问题。
- 可重复读(Repeatable Read)在该隔离级别下,一个事务在执行期间多次读取同一个数据时,得到的结果都是一样的。其他事务对数据的修改只有在本事务提交之后才会对本事务可见。这种隔离级别可以避免不可重复读的问题。
- 串行化(Serializable)在该隔离级别下,多个事务串行执行,相当于将并发执行的事务序列化,可以避免脏读、不可重复读和幻读(Phantom Read)等问题。但是,由于只允许串行执行,因此效率非常低下,通常不建议使用。
Mysql事务隔离
mysql提供了四种隔离级别,其中默认是可重复读,不同的数据库要用不同的命令查看隔离级别,mysql数据库命令如下:
设置数据库隔离级别为读未提交:
MariaDB [(none)]> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.001 sec)
设置数据库隔离级别为读已提交:
MariaDB [(none)]> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.000 sec)
设置数据库隔离级别为串行化:
MariaDB [(none)]> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.000 sec)
设置数据库隔离级别为可重复读:
-- 设置repeatable read级别:
set session transaction isolation level repeatable read;
脏读
脏读存在于读未提交,第一个人还没提交数据,第二个人就能读到数据,当第一个人后悔回滚后,第二个人又读取最早的数据。
将两个窗口设置完隔离级别为只读后查看信息:
首先开启事务
MariaDB [(none)]> begin;
Query OK, 0 rows affected (0.000 sec)
更改第一个窗口user中的密码,此时并未提交,但是第二个再查询信息显示已经修改:
MariaDB [coolshark]> update user set password='4321' where username='jerry';
Query OK, 1 row affected (0.000 sec)
Rows matched: 1 Changed: 1 Warnings: 0
脏读:是一个事务读取了另一个事务未提交的数据
不可重复读:是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
幻读:在同一个事务中,前后查询同一个范围内的数据时,发现后一次查询所得到的数据是前一次查询时所没有的。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读已提交 | x | √ | √ |
可重复读 | x | x | √ |
可串行化 | x | x | x |