一、事务

事务是由一组SQL语句组成的逻辑处理单元。
事务的特征ACID,即原子性、一致性、隔离性和持久性。
原子性(Atomicity)事务作为整体执行,操作要么全部执行、要么全部不执行。
一致性(Consistent)事务应该确保数据库状态从一个一致状态转变为另一个一致状态。
隔离性(Isolation)多个事务并发执行时,一个事务执行不影响其他事务执行(隔离级别可设置)。
持久性(Durable)事务提交后,对数据库的修改应该永久保存在数据库中。

二、事务的隔离级别

1、读未提交(Read Uncommited,RU)
这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用。
读取未提交的数据,又称为“脏读”。
 
2、读提交(Read commited,RC)
仅能读取到已提交的记录,这种隔离级别下,会存在幻读现象,所谓幻读是指在同一个事务中,多次执行同一个查询,返回的记录不完全相同的现象。幻读产生的根本原因是,在RC隔离级别下,每条语句都会读取已提交事务的更新,若两次查询之间有其他事务提交,则会导致两次查询结果不一致。虽然如此,读提交隔离级别在生产环境中使用很广泛。
 
3、可重复读(Repeatable Read,RR)
可重复读解决了幻读问题。不是所有的数据库都实现了该隔离级别。
 
4、串行化(Serializable)
在串行化隔离模式下,消除了脏读、幻读,但事务并发度急剧下降,事务的隔离级别与事务的并发度成反比,隔离级别越高,事务的并发度越低。实际生产环境下,dba会在并发和满足业务需求之间做权衡,选择合适的隔离级别。
 
 
三、关于锁
1、MySQL常用存储引擎的锁机制:
 
   MyISAM和MEMORY采用表级锁(table-level locking)
   BDB采用页面锁(page-level locking)或表级锁,默认为页面锁
   InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁
 
2、各种锁特点:
   表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
   行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
   页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
 
3、各种锁的适用场景:
  表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用
  行级锁则更适合于有大量按索引条件并发更新数据,同时又有并发查询的应用,如一些在线事务处理系统
 
4、死锁:
  是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
  表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB.
 
5.1 InnoDB锁类型
    共享锁(S):允许事务读一行数据
    排他锁(X):允许事务删除或更新一行数据
5.2 InnoDB意向锁(表级别)
    意向共享锁(IS):事务想要获得一个表中某几行的共享锁
    意向排他锁(IX):事务想要获得一个表中某几行的排他锁
5.3、对读操作进行枷锁
select .... lock in share mode:加S锁
select ... for update:加X锁
5.4、InnoDB锁算法
Record Lock:单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包括记录本身
Next-Key Lock:锁定一个范围的记录,并且包括记录本身(在Repeatable Read事务级别下,使用该算法,可避免幻读的产生)
 
6、InnoDB锁性能监控
 
mysql> show status like '%innodb_row_lock_%';
+-------------------------------+---------+
| Variable_name                 | Value   |
+-------------------------------+---------+
| Innodb_row_lock_current_waits | 0       |
| Innodb_row_lock_time          | 4517738 |
| Innodb_row_lock_time_avg      | 2673    |
| Innodb_row_lock_time_max      | 51386   |
| Innodb_row_lock_waits         | 1690    |
+-------------------------------+---------+
 
Innodb_row_lock_current_waits :当前等待锁的数量
Innodb_row_lock_time          :系统启动到现在锁定的总时间长度
Innodb_row_lock_time_avg      :每次平均锁定的时间
Innodb_row_lock_time_max      :最长一次锁定时间
Innodb_row_lock_waits         :系统启动到现在总共锁定次数
 
7、案例1
创建表
CREATE TABLE `class_teacher` (
`id` int() NOT NULL AUTO_INCREMENT,
`class_name` varchar() DEFAULT NULL,
`teacher_id` int() NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_teacher_id` (`teacher_id`)
) ENGINE=InnoDB; 插入数据
insert into class_teacher(class_name, teacher_id) values('class301', ),('class201', ); 根据二级索引进行更新(update或delete),之后进行插入[数据库隔离级别:REPEATABLE-READ]
)、
事务0: update class_teacher set class_name='class202' where teacher_id=; 事务1:insert into class_teacher(class_name,teacher_id) values('class229', );
[插入OK]
事务2:insert into class_teacher(class_name,teacher_id) values('class230', );
[插入WAIT]
事务3:insert into class_teacher(class_name,teacher_id) values('class231', );
[插入WAIT]
事务4:insert into class_teacher(class_name,teacher_id) values('class232', );
[插入WAIT]
事务5:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入WAIT] 结论:
锁定[,无穷大) )、
事务0: update class_teacher set class_name='class202' where teacher_id=; 事务1:insert into class_teacher(class_name,teacher_id) values('class210', );
[插入WAIT]
事务2:insert into class_teacher(class_name,teacher_id) values('class220', );
[插入WAIT]
事务3:insert into class_teacher(class_name,teacher_id) values('class230', );
[插入WAIT]
事务4:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入OK]
事务5:insert into class_teacher(class_name,teacher_id) values('class260', );
[插入OK] 结论:
锁定(无穷小,) )、
事务0: update class_teacher set class_name='class202' where teacher_id=; 事务1:insert into class_teacher(class_name,teacher_id) values('class240', );
[插入WAIT]
事务2:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入WAIT]
事务3:insert into class_teacher(class_name,teacher_id) values('class260', );
[插入WAIT]
事务4:insert into class_teacher(class_name,teacher_id) values('class215', );
[插入WAIT]
事务5:insert into class_teacher(class_name,teacher_id) values('class229', );
[插入WAIT]
事务6:insert into class_teacher(class_name,teacher_id) values('class230', );
[插入OK]
事务7:insert into class_teacher(class_name,teacher_id) values('class231', );
[插入OK] 结论:
锁定(无穷小,]和[,) )、
事务0:update class_teacher set class_name='class202' where teacher_id=; 事务1:insert into class_teacher(class_name,teacher_id) values('class240', );
[插入OK]
事务2:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入WAIT]
事务3:insert into class_teacher(class_name,teacher_id) values('class260', );
[插入WAIT]
事务4:insert into class_teacher(class_name,teacher_id) values('class215', );
[插入WAIT]
事务5:insert into class_teacher(class_name,teacher_id) values('class229', );
[插入WAIT]
事务6:insert into class_teacher(class_name,teacher_id) values('class230', );
[插入WAIT]
事务7:insert into class_teacher(class_name,teacher_id) values('class231', );
[插入WAIT]
事务8:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入WAIT] 结论:
锁定(,]和[,无穷大) )、
事务0: update class_teacher set class_name='class202' where teacher_id=; 事务1:insert into class_teacher(class_name,teacher_id) values('class240', );
[插入OK]
事务2:insert into class_teacher(class_name,teacher_id) values('class250', );
[插入WAIT]
事务3:insert into class_teacher(class_name,teacher_id) values('class260', );
[插入WAIT]
事务4:insert into class_teacher(class_name,teacher_id) values('class215', );
[插入WAIT]
事务5:insert into class_teacher(class_name,teacher_id) values('class229', );
[插入WAIT]
事务6:insert into class_teacher(class_name,teacher_id) values('class230', );
[插入OK]
事务7:insert into class_teacher(class_name,teacher_id) values('class231', );
[插入OK] 结论:
锁定[,)

 总结:当是根据二级索引进行更新,如update或delete时,在当前隔离级别下,其都会使用Next-Key锁[a,b)[行锁 + gap锁]前闭后开的,无法进行插入。


 备注:
 Repeatable Read,当使用非索引字段进行更新时,则会进行表锁。
 Read Uncommitted,数据库一般不用,且在其上的任何操作都不会加锁。
 Read Committed,有Record锁,没有Next-Key锁,即Next-Key锁变成了Record锁。

 
 
 

mysql小记--基础知识的更多相关文章

  1. MySQL数据库基础知识及优化

    MySQL数据库基础知识及优化必会的知识点,你掌握了多少? 推荐阅读: 这些必会的计算机网络知识点你都掌握了吗 关于数据库事务和锁的必会知识点,你掌握了多少? 关于数据库索引,必须掌握的知识点 目录 ...

  2. Mysql之基础知识笔记

    Mysql数据库基础知识个人笔记 连接本地数据库: mysql -h localhost -u root -p 回车输入数据库密码 数据库的基础操作: 查看当前所有的数据库:show database ...

  3. 阿里面试官必问的12个MySQL数据库基础知识,哪些你还不知道?

    数据库基础知识 1.为什么要使用数据库 (1)数据保存在内存 优点: 存取速度快 缺点: 数据不能永久保存 (2)数据保存在文件 优点: 数据永久保存 缺点: 1)速度比内存操作慢,频繁的IO操作. ...

  4. MySQL:基础知识

    基础知识 一.软件的生命周期 软件定义 软件开发 软件使用与维护 二.数据(Data) 1.定义 描述客观事物特征或性质的某种符号,经过数字化处理存储在计算机 2.数据独立性 物理独立性:指用户的应用 ...

  5. MySQL学习基础知识1

    什么是数据库? 数据库就是存储数据的仓库. 存储方式: 变量 无法永久存储 文件处理,可以永久存储,弊端:文件只能在自己的计算机读写,无法被分享(局域网除外) 数据库分类: 1.关系型数据库 提供某种 ...

  6. [mysql]数据库基础知识

    数据库管理系统DBMS 软件 bin config db (保存数据) 写程序: 数据库在本地 找到目录 添加数据 数据库在远程 socket连接上远程机器 socket发送命令 需要做的事情 程序 ...

  7. MySQL学习基础知识2

    1.基础语句 查 select(* | 字段名 | 四则运算 | 聚合函数) from 表名称; 加上as取别名 as可省略 如:select name, (math+english)/2 total ...

  8. Java基础86 MySQL数据库基础知识

    本文知识点(目录): 1.MySQL数据库的概述    2.MySQL数据库的管理[对数据库的操作](查询.删除.创建数据库,以及查询和修改数据库的编码模式)    3.表的管理[对数据库 表的操作] ...

  9. python week09 Mysql 数据库基础知识

    第一篇:初识数据库 注:<基础概念,不再赘述,点开链接查看> 第二篇:库相关操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些 ...

随机推荐

  1. Apache+lvs高可用+keepalive(主从+双主模型)

    Apache+lvs高可用+keepalive(主从+双主模型)     keepalive实验准备环境: httpd-2.2.15-39.el6.centos.x86_64 keepalived-1 ...

  2. Noesis.Javascript.dll 引用时报错“找不到指定的模块”

    Could not load file or assembly 'Noesis.Javascript.dll' or one of its dependencies. 找不到指定的模块. 通过反编译发 ...

  3. Laravel 5 基础(四)- Blade 简介

    在多个页面中我们可能包含相同的内容,像是文件头,链接的css或者js等.我们可以利用布局文件完成这个功能. 让我们新建一个布局文件,例如 views/layout.blade.php <!doc ...

  4. vs2010中的反编译

    有这样的需求,一个.dll文件,如何查看里面的代码呢?网上有很多关于反编译的运用的. http://blog.csdn.net/lyflcear/article/details/8102057 昨天( ...

  5. 浅谈 WPF布局

    我们首先来了解一下图形化用户界面(Graphic User Interface)也就是我们常常听到的GUI.举个简单的例子,同样是数据,我们可以用控制台程序加格式控制符等输出,但是这些都不如GUI来的 ...

  6. linux 文件在磁盘上的表示

    基本构成 分区就是把磁盘像比萨饼一样切成大小一样的扇形, 当然分区大小不一样扇形的大小也就不一样 上下一串盘片中,相同半径的磁道所组成的一个圆柱型的环壁,就称为柱面 在柱面组中, 比较重要的两个结构是 ...

  7. 深入PHP EOF(heredoc)用法详解

    介绍下使用EOF heredoc方式,输出长段内容的方法, <?php $name = '姓名'; print <<<EOT <html> <head> ...

  8. c语言变量作用域问题

    c语言中的变量作用域总结 不管什么语言,main好像总是程序的入口,大括号是它的内容:变量的作用域总是困扰着我们,接下来,我们循序渐进的搞明白c语言中的变量作用域,首先得知道c是弱类型的语言,弱类型表 ...

  9. c# 重载运算符(+-|&)和扩展方法

    通常我们需要对class的相加,相减,相乘 等重载以适应需求, 如caml查询的时候,我们可以定义一个caml类,然后来操作这些查询. 首先,我们定义一个class为Test public class ...

  10. Linux环境下的Nodejs

    最近在学习Node.js,在window下总是觉得不那么爽快.最简单而且环保的方法是在虚拟机中安装一个Linux. { 1.Linux:家中的Linux为Centos. 2.VirtuallyBox: ...