事务的四种特性
事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
- 原子性。事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
- 一致性。事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。
- 隔离性。一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持续性。也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
隔离级别以及其产生的问题
越往后隔离级别越高
- READ UNCOMMITTED 读取未提交
在这个隔离级别,所有的事务都可以“看到”未提交事务的执行结果。在这种级别上,可能产生很多问题,除非用户真的知道自己在做什么,并有很好的理由选择这样做。这种隔离级别很少用户实际应用,因为他的性能并不比其他性能好,而其他隔离界别有很多的优点,也被称之为脏读。
- READ COMMIT 读取提交
大多数数据库系统的默认隔离级别(不是Mysql的默认隔离级别),满足了隔离的早先简单定义:一个书屋开始时,只能“看见”已经提交的事务所有的改变,一个书屋从开始到提交前,所做的任何数据该病都是不可见的,除非已经提交。这种隔离界别也支持所谓的“不可重复读”。这意味着用户运行同一个语句两次,看到的结果是不同的。
- REPEATABLE READ 可重复读
MySql的默认隔离级别。解决了READ UNCOMMITTED隔离级别导致的问题。保证同一事务的多个实例在兵法读取事务时,会“看到同样的”数据行。不过这会导致另一个棘手的问题“幻读”。InnoDB和FaIcon存储引擎通过多版本并发控制机制(MVCC,Multiversion Concurrency Control)机解决了幻读问题。
- SERIVLIZABLE 可序列化
最高的隔离级别。它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。就是说他是每个读取的数据行加锁。可能导致大量的超时Timeout和锁竞争Lock Cotention现象,实际应用中很少使用这个级别,如果为了数据的稳定性,需要强制减少并发,也可以选择这个级别。
脏读
指的是一个事务读取到了未提交事务执行过程中的数据。
例如:线程A将余额100变成200,但是由于还要扣费没有执行结束,但是线程B已经看到了这200的余额,这就产生了脏读。即读取的数据并不一定是最后的结果数据,可能是过程数据。
不可重复读
指的是数据库中的某个数据,一个事务多次查询返回了不同的查询结果。原因是在事务的执行过程中,数据被其他数据修改。
例如:与A恰恰相反,事务两次查询执行到了不同的结果。
幻读
幻读是事务非独立执行时发生的一种现象。
例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | 是 | 是 | 是 |
read committed | 否 | 是 | 是 |
repeatable read | 否 | 否 | 是 |
serializable | 否 | 否 | 否 |
锁
- 基于锁的属性分类:共享锁(share lock),排他锁(exclusive lock)
- 共享锁
共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。 - 排它锁
排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
- 共享锁
- 基于锁的粒度分类:行级锁(innodb)、表级锁(innodb、myisam)、页级锁(innodb)
- 行级锁:用于单独锁定表中的一行
- 表级锁:
表示当前的操作对整张表加锁,资源开销比行锁少,不会出现死锁的情况,但是发生锁冲突的概率很大。被大部分的mysql引擎支持,MyISAM和InnoDB都支持表级锁,但是InnoDB默认的是行级锁。
- 页级锁:8 千字节 (KB) 的数据页或索引页
页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁。
- 基于锁的状态分为: 意向共享锁、意向排他锁
- 意向共享锁:表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
- 意向排他锁:类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁
- 基于业务类型区分
- 乐观锁:完全依靠数据库来管理锁的工作。
- 悲观锁:程序员自己管理数据或对象上的锁处理。
服务器托管,北京服务器托管,服务器服务器托管网租用 http://www.fwqtg.net