正文
只有串行化的隔离级别解决了全部这 3 个问题,其他的 3 个隔离级别都有缺陷。
一探究竟
下面,我们来一一分析这 4 种隔离级别到底是怎么个意思。
如何设置隔离级别
我们可以通过以下语句查看当前数据库的隔离级别,通过下面语句可以看出我使用的 MySQL 的隔离级别是 REPEATABLE-READ,也就是可重复读,这也是 MySQL 的默认级别。
# 查看事务隔离级别 5.7.20 之后
show variables like 'transaction_isolation';
SELECT @@transaction_isolation
# 5.7.20 之后
SELECT @@tx_isolation
show variables like 'tx_isolation'
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
稍后,我们要修改数据库的隔离级别,所以先了解一下具体的修改方式。
修改隔离级别的语句是:
set [作用域] transaction isolation level [事务隔离级别];
例如
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
其中作用于可以是
SESSION
或者
GLOBAL
,
GLOBAL
是全局的,而
SESSION
只针对当前回话窗口。隔离级别是
READ UNCOMMITTED
、
READ COMMITTED
、
REPEATABLE READ
、
SERIALIZABLE
这四种,不区分大小写。
比如下面这个语句的意思是设置全局隔离级别为读提交级别。
mysql> set global transaction isolation level read committed;
MySQL 中执行事务
事务的执行过程如下,以 begin 或者 start transaction 开始,然后执行一系列操作,最后要执行 commit 操作,事务才算结束。当然,如果进行回滚操作(rollback),事务也会结束。
需要注意的是,begin 命令并不代表事务的开始,事务开始于 begin 命令之后的第一条语句执行的时候。例如下面示例中,select * from xxx 才是事务的开始,
begin;
select * from xxx;
commit; -- 或者 rollback;
另外,通过以下语句可以查询当前有多少事务正在运行。
select * from information_schema.innodb_trx;
好了,重点来了,开始分析这几个隔离级别了。
接下来我会用一张表来做一下验证,表结构简单如下: