1.下载Mysql并安装,我喜欢不用安装的zip版,cd到bin目录下,先修改下mysql的密码.

mysqladmin -u root -p password mysql ,第一次运行并修改mysql的密码为mysql,注册mysqld服务,mysqld -install

2.四种数据不一致性的问题

1)       丢失或覆盖更新(lost update)

当两个或多个事务选择同一数据,并且基于最初选定的值更新该数据时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。上面预定飞机票的例子就属于这种并发问题。事务1与事务2先后读入同一数据A=16,事务1执行A-1,并将结果A=15写回,事务2执行A-1,并将结果A=15写回。事务2提交的结果覆盖了事务1对数据库的修改,从而使事务1对数据库的修改丢失了。
(2)    脏读
一个事务读取了另一个未提交的并行事务写的数据。当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。换句话说,当事务1修改某一数据,并将其写回磁盘,事务2读取同一数据后,事务1由于某种原因被撤销,这时事务1已修改过的数据恢复原值,事务2读到的数据就与数据库中的数据不一致,是不正确的数据,称为脏读。
例如,在下图中,事务1将C值修改为200,事务2读到C为200,而事务1由于某种原因撤销,其修改作废,C恢复原值100,这时事务2读到的就是不正确的“脏“数据了。
(3)    不可重复读(nonrepeatable read)
一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务修改过。即事务1读取某一数据后,事务2对其做了修改,当事务1再次读数据时,得到的与第一次不同的值。
(4)    幻像读
如果一个事务在提交查询结果之前,另一个事务可以更改该结果,就会发生这种情况。这句话也可以这样解释,事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2删除了其中部分记录,事务1再次按相同条件读取数据时,发现某些记录神秘地消失了;或者事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录。

3.数据库的隔离级别

===========================================================================================隔离级别               脏读(Dirty Read)          不可重复读(NonRepeatable Read)     幻读(Phantom Read)
===========================================================================================未提交读(Read uncommitted)        可能                            可能                       可能已提交读(Read committed)          不可能                          可能                        可能可重复读(Repeatable read)         不可能                          不可能                     可能可串行化(Serializable )           不可能                          不可能                     不可能===========================================================================================·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)·可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

3.新建一个表(testTx),测试Transaction,并插入一行数据

CREATE TABLE testTx (
id int(8) primary key auto_increment,
version int(8)
);
insert into testTx values (1,1);

mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@GLOBAL.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+

查看Mysql的默认的隔离级别是REPEATABLE-READ.

为什么叫可重复读的隔离级别,就是因为在此种隔离级别下,可以避免不可重复读的问题。

T1 T2

set autocommit=0;

begin;//开始事务

set autocommit=0;

begin;//开始事务

mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       1 |
+----+---------+

 
mysql> update testTX set version =2 where id =1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from testisolatio;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+
1 row in set (0.00 sec)

mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       1 |
+----+---------+

【说明】
T2未提交,看到数据不变,无脏读。

 
   commit;
mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       1 |
+----+---------+

【说明】
T2提交,看到数据依旧变,说明可以重复读。

 
 commit;  
mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+

事务提交之后,看到数据改变

 
   

以上就是mysql的可重复读隔离模式下的两个事务的执行过程,我们再来看在REPEATABLE-READ模式下的幻读问题。

Session1 Session2
begin; begin;
mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+
 
 

INSERT INTO teseTX VALUES (2, 1);

mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+Session2 未提交,依然是可重复读
 
  commit;
mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+Session2 已提交,数据依然和之前读出来一样.但是幻读问题依然有
 

INSERT INTO teseTX VALUES (2, 1);

ERROR 1062 (23000):
Duplicate entry '1' for key 1

(shit, 刚刚明明显示只有id=1的记录),这里出现了幻读

 
 commit;  
mysql> select * from testTx;
+----+---------+
| id | version |
+----+---------+
|  1 |       2 |
+----+---------+|  2 |       1 |+----+---------+
最终显示了
 

但是Mysql提供了在REPEATABLE-READ模式下解决幻读的问题。

http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html
To prevent phantoms, InnoDB uses an algorithm called next-key locking that combines index-row locking with gap locking. InnoDB performs row-level locking in such a way that when it searches or scans a table index, it sets shared or exclusive locks on the index records it encounters. Thus, the row-level locks are actually index-record locks. In addition, a next-key lock on an index record also affects the “gap” before that index record. That is, a next-key lock is an index-record lock plus a gap lock on the gap preceding the index record. If one session has a shared or exclusive lock on record R in an index, another session cannot insert a new index record in the gap immediately before R in the index order.

再看一个实验,要注意,表TesetTX里的id为主键字段。实验三:

   
begin; begin;

mysql> select * from testTX where id<2 for update;
+----+---------+
| id | version |
+----+---------+
| 1 | 2 |
+----+---------+
1 row in set (15.84 sec)

 
 

INSERT INTO teseTX VALUES (3, 1);
Query OK, 1 row affected

mysql> select * from testTX where id<2 for update;
+----+---------+
| id | version |
+----+---------+
| 1 | 2 |
+----+---------+
1 row in set (15.84 sec)
 
 

mysql> select * from testTX where id<=1 for update;

(waiting for lock ... then timeout)
 ERROR 1205 (HY000): Lock wait timeout exceeded;
 try restarting transaction

   commit;
 commit;  

mysql> select * from testTX;
+----+---------+
| id | version |
+----+---------+
| 1 | 2           |
+----+---------+

| 2 | 1           |
+----+---------+

| 3 | 1          |
+----+---------+
1 row in set (15.84 sec)

 
   

可以看到,用id<2加的锁,只锁住了id<2的范围,可以成功添加id为3的记录,但一旦想要获得select id<=1,就会阻塞,等待。

MySQL InnoDB的可重复读并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是next-key locks。

转载于:https://www.cnblogs.com/fengjian/p/3778047.html

Mysql讲解数据库并发控制知识相关推荐

  1. java学习与总结:MySQL和数据库基础知识

    文章目录 MySQL MySQL数据库索引数据结构 B树和B+树的区别 MySQL一条数据是怎么保存到数据库的 WAL : WRITE AHEAD LOG binlog 和 redo log 流程 M ...

  2. 【MySQL】数据库理论知识

    1.数据库系统和数据库管理系统 DBMS:数据库管理系统,是位于用户与操作系统之间的一层数据管理软件,用于科学地组织.存储和管理数据.高效地获取和维护数据. DBS:数据库系统,指在计算机系统中引入数 ...

  3. 虚拟机安装mysql及数据库基础知识一

    一.安装前的准备 首先要准备好安装环境: ① 准备一台有IP地址的虚拟机 ② 使用winscp把数据库安装包传到虚拟机中 安装包可自行去官网下载 mysql官网 ③ 进行mysql的安装 二.安装 1 ...

  4. mysql多数据库并发控制_什么是数据库并发控制?数据库并发控制的主要方法是?...

    务处于何种状态, 以此确定是撤销该事务所做出的所有修改操作, 还是将修改的操作重新执 行. ( 2 )一致性 一致性要求事务执行完成后, 将数据库从一个一致状态转变到另一个一致状态. 它是一种以 一致 ...

  5. [Python从零到壹] 八.数据库之MySQL和Sqlite基础知识及操作万字详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  6. mysql查看数据库表大小语句_MySQL查看数据库表容量大小的命令语句讲解

    MySQL查看数据库表容量大小的命令语句讲解 发布时间:2020-04-27 14:17:23 来源:亿速云 阅读:180 作者:三月 本文主要给大家介绍MySQL查看数据库表容量大小的命令语句讲解, ...

  7. MariaDB/Mysql数据库进阶知识

    这一篇章主要说一下关于MariaDB/Mysql的一些进阶知识,希望可以加深自己的理解 MariaDB的特性 插件式存储引擎:也称为"表类型",存储管理器有多种实现版本,功能和特性 ...

  8. 1.0 MySQL数据库基础知识

    MySQL数据库基础知识 MYSQL介绍 MySQL分支版本的发展 MySQL. Oracle. SQLServer的市场区别 MYSQL数据库使用上的结构 MYSQL体系架构图 MYSQL体系架构- ...

  9. Mysql数据库基础知识(五)之:视图、变量、存储过程、函数、流程控制结构

    第一部分:Mysql数据库基础知识(一)之 基础查询----分组查询 第二部分:Mysql数据库基础知识(二)之 连接查询----子查询-----分页查询------union联合查询 第三部分:My ...

最新文章

  1. JAVA《第一次作业》
  2. android学习日记24--Android 菜单开发
  3. 【直播预告】阿里云服务网格 ASM 产品易用性改善实践与思考
  4. Nginx中gzip_static使用测试
  5. qt 最小化到托盘linux,Qt窗口最小化到托盘,托盘菜单控制
  6. angular下拉框点击无反应_angular 实现 下拉菜单 的 点击其他区域关闭下拉菜单功能?...
  7. python成绩区间曲线图_Python重现论文图表之【包含置信区间的折线柱状图】
  8. bzoj 5094: 硬盘检测(概率)
  9. R语言重抽样与自助法
  10. Python3实现文件名排序
  11. hdu 4723 How Long Do You Have to Draw(贪心)
  12. 第二届中国计量大学ACM程序设计竞赛个人赛(同步赛)B-Little Gyro and Sets【两个等差数列公式】
  13. 科技部:中国131家独角兽企业 名单文字版
  14. 网页动画的12原则,帮你做出漂亮的动画效果
  15. 【飞鱼SEO】sem竞价的特点以及相关规则
  16. DFX:面向产品生命周期的设计
  17. php算法----队列
  18. 网站SEO报告和代码工具平台系统源码
  19. 浅谈基于 OpenStack 和 k8s 轻量研发私有云建设
  20. DAB变换器的变频控制

热门文章

  1. 文化的作用与本质是什么
  2. 社会化生态农场品,社群+农产品,大有搞头
  3. 直播电商只能卖便宜货吗?
  4. 无人驾驶出租车已经在北京全面开放,未来普通人还需要学驾照吗?
  5. 编写int testsyscall()系统调用–响应函数
  6. 修饰类方法(静态方法)
  7. 十多年前国内的三大杀毒软件瑞星、江民和金山毒霸的现状如何?
  8. Mysql的int和bigint字段类型,映射到Java的Integer和Long类型时,勾选UNSIGNED无符号会导致越界转换。
  9. 删除不需要的(辅助)SQL Server事务日志文件
  10. mysql升级mysql5.7.22记录