Heim >Datenbank >MySQL-Tutorial > 浅谈mysql中不同事务隔离级别下数据的显示效果
事务的概念事务是一组原子性的SQL查询语句,也可以被看做一个工作单元。如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一
写锁:独占锁,由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁
锁粒度:从大到小,MySQL服务器仅支持表级锁,行锁需要存储引擎完成。
表锁:锁定某个表
页锁:锁定某个页
行锁:锁定某行
粒度越精细,并发性越好。即行锁的并发性最好,但需要存储引擎的支持。
事务的四种隔离级别
读未提交(read uncommitted): 允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
读提交(read committed): 只能读取到已经提交的数据。oracle等多数数据库默认都是该级别
可重读(repeatable read): 在同一个事务内的查询都是事务开始时刻一致的,innodb的默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
可串行(serializable): 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
在MySQL中,在并发控制情况下,不同隔离级别分别有可能产生问题如下所示:
上边之所以介绍那么多理论知识,是为了便于理解。在上边的表格中已经列出来了,在不同隔离级别下,数据的显示效果可能出现的问题,现在在linux上安装好mysql,通过我们的实验来一起看一下在不同隔离级别下数据的显示效果吧。
实验环境:
linux系统:RedHat 5.8
linux内核:linux-2.6.18-308.el5
mysql版本:mysql-5.6.10-linux-glibc2.5-i686
本次实验的所有操作均在虚拟机中完成,通过Xmanager连接虚拟机,然后打开两个会话连接,在两个会话中,同时更改隔离级别,然后查看数据的显示效果。
本次实验中mysql采用源码编译安装的方式安装mysql,你也可以使用rpm包的方式直接安装mysql。具体源码安装的方式及过程,这里不再演示,在前面的博客中,我已经介绍了很多次。如果你采用源码编译安装的方式,不知道如何安装mysql,可参看我以前写的博客,里边都有介绍。采用源码编译安装的方式,在mysql的配置文件中,最好启用每表一个表空间。这里我们直接启用。
因为是实验,这里没有对mysql设置密码,因此,香港空间,我们直接使用命令进入mysql。命令及显示效果如下:
[root@mysql ~]# mysql -uroot -p #使用该命令进入mysql,因为没有设置密码,在要求输入密码时直接按回车键即可 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.10 MySQL Community Server (GPL) Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like '%iso%'; #查看mysql默认的事务隔离级别,默认为可重读。也可以使用select @@tx_isolation命令查看 +-----------------+------------------+ | Variable_name | Value | +-----------------+------------------+ | tx_isolation | REPEATABLE-READ | +-----------------+------------------+ 1 row in set (0.36 sec) mysql> show databases; #查看系统已经存在的数据库 +---------------------+ | Database | +---------------------+ | information_schema | | mysql | | performance_schema | | test | +---------------------+ 4 rows in set (0.00 sec) 现在导入我们实验所使用的数据库。 [root@mysql ~]# mysql show databases; #查看导入的jiaowu数据库是否存在 +----------------------+ | Database | +----------------------+ | information_schema | | jiaowu | | mysql | | performance_schema | | test | +----------------------+ 5 rows in set (0.01 sec)
我们在mysql命令界面下,没有明确启用事务时,输入的每个命令都是直接提交的,因为mysql中有个变量的值,可实现自动提交。也就是说我们每输入一个语句,都会自动提交,这会产生大量的磁盘IO,降低系统的性能。在我们做实验时,因为我们要明确使用事务,所以,建议关闭自动提交的功能,如果不关闭也没有关系,但是如果你没有明确使用事务,想要做下边的实验,那就需要关闭此功能了。这里,我们明确使用事务,且关闭自动提交功能。假如你关闭了自动提交功能,需明确使用事务,否则你输入的所有语句会被当成一个事务进行处理。命令如下:
mysql> select @@autocommit; #查看该值,为1表示启动自动提交 +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec) mysql> set autocommit=0; #关闭自动提交功能 Query OK, 0 rows affected (0.00 sec) mysql> select @@autocommit; #重新查看该值,为0表示关闭自动提交功能 +--------------+ | @@autocommit | +--------------+ | 0 | +--------------+ 1 row in set (0.00 sec)