事务的概念事务是一组原子性的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 2server 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 itsaffiliates. other names may be trademarks of their respectiveowners.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)