脏读 两个事务,第一个事务修改了数据但是没有提交,这时第二个事务读取了第一个事务没有提交的数据,称之为脏读。
不可重复读 两个事务,第一个事务读取一条数据,这时第二个事务修改了或者提交了第一事务读取的数据。再第一个事务内再次读取与第一次读取数据不一致,称之为不可重复读。
幻读 两个事务,第一个事务修改了表所有行并没有提交,这时第二个事务往数据表中新增了一条数据并提交结果就会发现数据里还有没有修改的数据行,称之为幻读。
------------根据以上问题解决方案------------
MySQL配置隔离级别
读未提交(read-uncommitted)会出现脏读、不可重复读、幻读;
不可重复读or读提交(read-committed)会出现不可重复读、幻读;不会出现脏读;
可重复读(repeatable-read)会出现幻读;不会出现脏读、不可重复读;
串行化(serializable)不会出现脏读、不可重复读、幻读;
实例
root@dongyue-virtual-machine:/var# mysql -V
mysql Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using EditLine wrapper
//查看MySQL服务状态,主要是是否启动
$ /etc/init.d/mysql status
//同过(命令行)接口登录
$ mysql -uroot -proot
//查看事务默认级别
$ mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.70 sec)
//修改当前事务隔离级别
//用户A
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update account set money=money-1 where id = 1;
Query OK, 1 row affected (0.09 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
//用户B
//事务A前
mysql> select * from account where id = 1;
+----+-------+
| id | money |
+----+-------+
| 1 | 1106 |
+----+-------+
1 row in set (0.00 sec)
//事务A进行中并未提交
mysql> select * from account where id = 1;
+----+-------+
| id | money |
+----+-------+
| 1 | 1105 |
+----+-------+
1 row in set (0.00 sec)
总结:MySQL隔离级别分为当前会话(session)和全局(global);MySQL默认事务隔离级别为可重复读(repeatable-read),根据业务不同;可以做相关调整。
文献来自书籍;