MySQL事务隔离级别详解
来源:互联网 发布:健身房健身计划软件 编辑:程序博客网 时间:2024/06/11 16:12
一、什么是事务
1.概念:事务是包含了一组有序的数据库操作命令的序列,它是数据库并发操作的最小控制单位。
2.特性:
原子性:事务包含的数据库操作命令要么都执行,要么都不执行。
一致性:当事务完成时,数据库处于稳定而一致的状态。即事务执行后,数据库数据要符合规定,而且所有数据查询的结果是一致的。
隔离性:多个事务同时执行时,他们之间是互不干扰的。永久性:一旦事务提交成功,它引发的变化也就永久保存了下来,硬件与应用程序发生错误也不能改变。
二、在并发执行事务时会发生什么问题呢?
1、脏读:一个事务读到另一个事务未提交的更新数据。
2、不可重复读:一个事务读到另一个事务已提交的更新数据。
3、幻读:一个事务读到另一个事务已提交的新插入的数据。
三、四种隔离级别
1、Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。
2、Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。
3、Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。
1、Serializable(串行化):事务执行的时候不允许别的事务并发执行。
四、通过例子理解事务的4种隔离级别
首先,我们使用test数据库,新建test表,如下:+-------+------------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------+------------------+------+-----+---------+----------------+| id | int(10) unsigned | NO | PRI | NULL | auto_increment || name | varchar(20) | NO | UNI | NULL | |+-------+------------------+------+-----+---------+----------------+
接着开启两个客户端。
第1级别:Read Uncommitted(读取未提交内容)
所有事务都可以看到其他未提交事务的执行结果,该级别会引发脏读。例子:
#首先,修改隔离级别set tx_isolation='READ-UNCOMMITTED';select @@tx_isolation;+------------------+| @@tx_isolation |+------------------+| READ-UNCOMMITTED |+------------------+#事务A:启动一个事务start transaction;select * from test;+------+------+| id | name |+------+------+| 1 | tom || 2 | amy || 3 | sam |+------+------+#事务B:启动一个事务,执行更新,且不提交start transaction;update test set name=sun where id=1;select * from test;+------+------+| id | name |+------+------+| 1 | sun || 2 | amy || 3 | sam |+------+------+#事务A:那么这时候事务A能看到这个更新了的数据吗?select * from test;+------+------+| id | name |+------+------+| 1 | sun |-->可以看到!说明我们读到了事务B还没有提交的数据| 2 | amy || 3 | sam |+------+------+#事务B:事务B回滚,仍然未提交rollback;select * from test;+------+------+| id | name |+------+------+| 1 | tom || 2 | amy || 3 | sam |+------+------+#事务A:在事务A里面看到的也是B没有提交的数据select * from test;+------+------+| id | name |+------+------+| 1 | tom || 2 | amy || 3 | sam |+------+------+脏读意味着在这个事务中(A中),事务B虽然没有提交,但它任何一条数据变化,事务A都可以看到!
第2级别:Read Committed(读取提交内容)
这个级别是大多数数据库系统的默认隔离级别,但MySQL不是;在这个级别,一个事务只能看见已经提交事务所做的改变;这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read)。例子:
#首先修改隔离级别set tx_isolation='read-committed';select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+#事务A:启动一个事务start transaction;select * from test;+------+------+| id | name |+------+------+| 1 | tom || 2 | amy || 3 | sam |+------+------+#事务B:启动一个事务,更新数据,且未提交start transaction;update test set name=sun where id=1;select * from test;+------+------+| id | name |+------+------+| 1 | sun || 2 | amy || 3 | sam |+------+------+#事务A:这个时候我们在事务A中能看到数据的变化吗?select * from test;+------+------+| id | name |+------+------+| 1 | tom |-->并不能看到| 2 | amy || 3 | sam |+------+------+#事务B:如果提交了事务B呢?commit;#事务A:select * from test;+------+------+| id | name |+------+------+| 1 | sun |-->事务B提交之后事务A可以看到| 2 | amy || 3 | sam |+------+------+
第3级别:Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行;此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行;InnoDB和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了该问题。例子:
#首先,更改隔离级别set tx_isolation='repeatable-read';select @@tx_isolation;+-----------------+| @@tx_isolation |+-----------------+| REPEATABLE-READ |+-----------------+#事务A:启动一个事务start transaction;select * from test;+------+------+| id | name |+------+------+| 1 | tom || 2 | amy || 3 | sam |+------+------+#事务B:开启一个新事务,更新数据,并提交start transaction;update test set name=sun where id=1;select * from test;+------+------+| id | name |+------+------+| 1 | sun || 2 | amy || 3 | sam |+------+------+commit;#事务A:这时候即使事务B已经提交了,但A能不能看到数据变化?select * from test;+------+------+| id | name |+------+------+| 1 | tom |-->看不到| 2 | amy || 3 | sam |+------+------+#事务A:只有当事务A也提交了,它才能够看到数据变化commit;select * from test;+------+------+| id | name |+------+------+| 1 | sun || 2 | amy || 3 | sam |+------+------+
第4级别:Serializable(可串行化)
这是最高的隔离级别,它在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。例子:
#首先修改隔离级别set tx_isolation='serializable';select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| SERIALIZABLE |+----------------+#事务A:开启一个新事务start transaction;#事务B:在A没有commit之前,这个交叉事务是不能更改数据的start transaction;insert test values('cat');ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionupdate test set name=sun where id=1;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
阅读全文
1 0
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- MySQL事务隔离级别详解
- tomcat上传超过限制文件大小报异常而不能正常转发的bug
- ISCC之pwn1格式化字符串漏洞详解!
- Python命令行工具开发之二:使用optparse模块编写命令行工具
- 正则表达式及其常用特殊符号和字符
- hiho1305区间求差
- MySQL事务隔离级别详解
- 数据结构之总述
- 索尼新型CMOS图像传感器内置偏振元件
- find命令进阶(二):对找到的文件执行操作exec
- LC 2 pointer summary
- 数学中的特殊字符
- 算法导论程序35--动态规划(钢条切割)
- 编译的过程
- H