高性能MySql学习笔记——锁、事务、隔离级别(转)

为什么需要锁?

因为数据库要解决并发控制问题。在同一时刻,可能会有多个客户端对Table1.rown进行操作,比如有的在读取该行数据,其他的尝试去删除它。为了保证数据的一致性,数据库就要对这种并发操作进行控制,因此就有了锁的概念。

锁的分类

从对数据操作的类型(读\写)分

读锁(共享锁):针对同一块数据,多个读操作可以同时进行而不会互相影响。

写锁(排他锁):当当前写操作没有完成前,它会阻断其他写锁和读锁。

从锁定的数据范围分

表锁

行锁

为了尽可能提高数据库的并发度,每次锁定的数据范围越小越好,理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗资源的事情(涉及获取,检查,释放锁等动作),因此数据库系统需要在高并发响应和系统性能两方面进行平衡,这样就产生了“锁粒度(Lock granularity)”的概念

锁粒度(Lock granularity)

表锁:管理锁的开销最小,同时允许的并发量也最小的锁机制。MyIsam存储引擎使用的锁机制。当要写入数据时,把整个表都锁上,此时其他读、写动作一律等待。在MySql中,除了MyIsam存储引擎使用这种锁策略外,MySql本身也使用表锁来执行某些特定动作,比如alter table.

行锁:可以支持最大并发的锁策略。InnoDB和Falcon两张存储引擎都采用这种策略。

MySql是一种开放的架构,你可以实现自己的存储引擎,并实现自己的锁粒度策略,不像Oracle,你没有机会改变锁策略,Oracle采用的是行锁。

事务(Transaction)

从业务角度出发,对数据库的一组操作要求保持4个特征:

Atomicity:原子性

Consistency:一致性,

Isolation:隔离性

Durability:持久性

为了更好地理解ACID,以银行账户转账为例:

1 START TRANSACTION;

2 SELECT balance FROM checking WHERE customer_id = 10233276;
3 UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
4 UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;
5 COMMIT;

原子性:要么完全提交(10233276的checking余额减少200,savings 的余额增加200),要么完全回滚(两个表的余额都不发生变化)

一致性:这个例子的一致性体现在 200元不会因为数据库系统运行到第3行之后,第4行之前时崩溃而不翼而飞,因为事物还没有提交。

隔离性:允许在一个事务中的操作语句会与其他事务的语句隔离开,比如事务A运行到第3行之后,第4行之前,此时事务B去查询checking余额时,它仍然能够看到在事务A中被减去的200元,因为事务A和B是彼此隔离的。在事务A提交之前,事务B观察不到数据的改变。

持久性:这个很好理解。

事务跟锁一样都会需要大量工作,因此你可以根据你自己的需要来决定是否需要事务支持,从而选择不同的存储引擎。

隔离级别(Isolation Level)

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
Read Uncommitted(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:

http://www.cnblogs.com/wenfeng762/archive/2011/11/06/2237253.html

 

时间: 2024-12-22 14:35:37

高性能MySql学习笔记——锁、事务、隔离级别(转)的相关文章

【MySQL】MySQL的四种事务隔离级别

[MySQL]MySQL的四种事务隔离级别 本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样.也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位.  2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束

MySQL中Innodb的事务隔离级别和锁的关系的讲解教程_Mysql

前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一次封锁or两段锁?因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会用

高性能mysql学习笔记总结

(架构及历史) Mysql逻辑架构 如果能在脑中有个Mysql各组件如何协同工作的架构图,这会很有助于我们了解Mysql服务器. Mysql逻辑架构图 最上层连接/线程处理这里,处理连接.授权和安全. 第二层是解析器.查询缓存.优化器这三部分.处理查询解析.分析.优化.缓存以及所有内置函数.所有跨存储引擎的功能(存储过程.触发器.视图). 第三层就是存储引擎了.服务器通过API与各种存储引擎交互,这些接口屏蔽了不同存储引擎的差异. 另外Mysql还有各方面的特性,包括:执行与优化.并发控制.读写

[用事实说明两个凡是]一个由mysql事务隔离级别造成的问题分析

背景 最近要做一个批跑服务, 基本逻辑就是定时扫描数据库的记录, 有满足条件的就进行处理(一条记录代表一个任务,以下任务与记录含义相同). 要求支持多机部署批跑服务. 批跑支持多机部署实现方案 要实现多机部署, 只要保证每个批跑服务实例每次只获取一条记录, 处理完再获取下一条即可. 其中最种要的是避免不同的实例获取到同一条记录,即所谓抢任务. 先看表结构设计: create database if not exists ae; create table ae.task ( id int prim

MySQL的事务隔离级别和锁

MySQL的事务隔离级别:Read Uncommitted[读未提交数据]Read Committed[读已提交数据]Repeatable Read[可重读]Serializable[可串行化] 查看MySQL的事务隔离级别:默认.全局和会话事务隔离级别: SELECT @@tx_isolation SELECT @@global.tx_isolation; SELECT @@session.tx_isolation; mysql> select @@tx_isolation; +-------

浅谈MySQL中的事务隔离级别(r11笔记第86天)

   之前写了一篇浅谈事务(一),算是对事务的一个基本认识,今天来简单总结一下事务的隔离级别,虽然是老掉牙的知识点,重温一下还是值得的.    在MySQL中基本有这两种事务隔离级别的设置,默认的RR(Repeatable-Read)和实际中常见的RC(Read-Committed).两者区别是什么,怎么正确理解,用几个SQL语句就能说明白,就用简单的实验来说明白.    我们开始吧.        首先创建一个测试表test,插入一些数据. create table test( id int

【转】Innodb中的事务隔离级别和锁的关系

申明: 本文转自Innodb中的事务隔离级别和锁的关系,解决了我关于锁.事务隔离的一些误解和疑问.在高并发系统中,数据库对高并发的支持是非常重要的一个方面,本文主要描述高并发场景下,数据库如何保证数据一致性(同时保证良好的性能). 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过

MySQL数据库事务隔离级别介绍(Transaction Isolation Level)_Mysql

数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 复制代码 代码如下:  #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. [mysqld] transaction-isolation = REPEATABLE-READ 这里全局默认是REPEATABLE-READ,其实MySQL本来默认也是这个级

mysql中不同事务隔离级别下数据的显示效果

  事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都不会执行.也就是说,事务内的语句要么全部执行,要么一句也不执行. 事务的特性:acid,也称为事务的四个测试(原子性,一致性,隔离性,持久性) automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行 consisitency:一致性,事务执行前的总和和事务执行后的总和是不