数据库事务和锁
2016-03-20 本文已影响982人
环球探测
参考链接:
MySQL中Innodb的事务隔离级别和锁的关系
1. 事务
事务:事务是作为单个逻辑单元工作执行的一些列操作。可以是一条SQL语句,也可以是多条。
ACID:事务具有四个特性:
- 原子性(Atomic):整个事务是不可分割的工作单位。
- 一致性(Consistency):指的是事务不能破坏关系数据的完整性以及业务逻辑的一致性。
- 隔离性(Isolation):在并发环境中,当不同的事务同时操作相同数据的时候,每个事务会拥有各自的独立完整数据空间。
- 持久性(Durability):指的是只要事务成功完成,它对数据库所做的更改必须永久保存下来。
隔离级别:事务由低到高可以分为4个隔离级别:
- READ UNCOMMITTED(读取未提交内容):所有事务都可以读取未提交事务的执行结果,造成“脏读”。实际很少应用.
- READ COMMITED(读取提交内容):大多数数据库系统默认的隔离级别(但不是MySQL默认)。一个事务从开始到提交前,所做的任何数据改变都是不可变的。一个事务开始时,只能“看到”已经提交的事务作出的改变。这种级别是不可重复读的,意味着用户运行同一条语句两次,看到的结果是不同的。
- REPEATABLE READ(可重读):MySQL默认的隔离级别,确保同一个事务的多个实例在并发读取数据的时候,会看到同样的数据行。但是该隔离界别会导致“幻读”,幻读是指用户读取某一个范围的数据行时,另一个事务又在该范围插入了新行,当用户再读取该范围的时候,会发现有新的“幻影”行。InnoDB通过多版本并发控制机制(MVCC)解决的幻读的问题。
- SERIALIZABLE (可串行化):最高隔离界别,它通过强制事务排序,是之不可能相互冲突,从而解决幻读问题。在这个级别,每个事务都会在每个在读的数据行加锁,导致大量锁竞争和超时现象。
事务一般是由事务日志实现的。
浅谈SQL Server中的事务日志和三种恢复模式
2. 锁
共享锁和排他锁:在一般的应用中,为了应付大量并发,我们一般使用一次封锁法,在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。在这种方法在数据库中却不适用,因为在事务开始阶段,数据库并不知道会用到哪些数据。数据库遵循的是两段锁协议,将事务分成两个阶段,加锁阶段和解锁阶段(所以叫两段锁)。
- 加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁(共享锁,其它事务可以继续加共享锁,但不能加排它锁),在进行写操作之前要申请并获得X锁(排它锁,其它事务不能再获得任何锁)。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
- 解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。
大多数数据库的MVCC通过对数据版本的乐观锁实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。