数据库事务和事务隔离级别

来源:互联网 发布:mac flv 编辑:程序博客网 时间:2024/05/21 10:22

什么是事务?

事务的定义很简单,就是一组操作,这些操作要么都执行,要么都不执行,这一组操作是不可分割的.在数据库中,事务具有ACID特性.也就是原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability).

原子性

原子性是指事务是一个不可分割的一组操作,要么都发生,要么都不发生.这里常见的例子就是银行转账的例子:
若A账户需要给B账户转100元钱,那么分别有两个操作,A账户扣除100元钱,B账户增加100元钱,这两个操作就不可分割.

一致性

一致性是指在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏.
还是用转账的例子,比如A账户和B账户加起来总共有1000元钱,那么A和B之前不管怎么转账,最终A和B两个账户加起来的钱还是1000.

隔离性

多个事务并发执行的时候,事务之间是隔离的,一个事务不应该影响其它事务运行的结果.
然而隔离是有级别的,不同的隔离等级造成的情况也不相同.下面将会介绍到.

持久性

持久性意味着在事务完成后,该事务对数据库做的更改便会存于数据库中,即使出现断电等事故,事务一旦提交,数据就持久化在数据库中.


事务隔离级别

事务的隔离级别分为四个等级,不同等级会出现的问题也不一样,如下表:

种类 脏读 不可重复读 幻读 Read uncommitted √ √ √ Read committed × √ √ Repeatable read × × √ Serializable × × ×

我们来看一下这几种事务隔离级别:

Read uncommitted

Read uncommitted(读未提交):处在这种事务隔离等级时,当一个事务去读取数据时,可以读取其他事务还未提交的数据.举个例子:

事务A去读取一行数据,这时事务B将这行数据进行了更改(但是事务B没有提交),事务A将数据读出展示,事务B回滚了,这时,事务A读取出来的数据其实是不对的,这也就是我们所谓的脏读.


Read committed

Read committed(读提交):这种事务隔离等级也是数据库默认的事务隔离等级(MySQL不是,MySQL的事务隔离等级默认是Repeatable read).这种事务等级就是会读取其他事务已经提交的数据,举个例子:

事务A去读取一行数据(读两遍),第一遍读取的时候,事务B将这行数据进行了更改(但是事务B没有提交),因为事务隔离等级处在Read cmooitted,所以事务A读取的数据不会受事务B的影响,然后事务第二遍去读这个数据,这个时候,事务B已经提交了,所以第二遍事务A读取的数据是事务B已经更改了的数据,所以造成的结果是事务A第一遍读的数据和第二遍读的数据不一样,这就是我们所谓的不可重复读.


Repeatable read

Repeatable read(重复读):这种等级是可以避免不可重复读的,但是无法避免幻读,举个例子:

事务A去修改所有数据的一个字段,这时,事务B向表中插入了一条新的记录,事务A提交之后会发现,明明更新了所有数据,但是有一条记录就没有更新,这就是所谓的幻读.


Serializable

Serializable(串行):这种等级可以避免上述所有的情况.


事务隔离级别分析

我们来简单的思考一下,数据库是如何实现这些事务隔离级别的,为了避免多个事务对同一条记录的操作,一般我们首先想到的就是可能是通过锁实现的.

Read Uncommited:这种方式应该不会加任何锁.
Read commited:这种方式可以避免脏读,那应该是对所读的数据加锁了,但是又会出现不可重复读,所以应该是在事务中,读数据时会加锁,而读完锁就释放.
Repeatable Read:这种方式不仅避免脏读,还避免了不可重复读,所以应该是读数据时加锁,并且这个锁是到事务结束时才会释放.
Serializable:这种方法避免了幻读,所以猜测可能不仅仅是对自己所操作的数据都加锁,可能还会锁定一个范围,比如将整个表锁住.

0 0
原创粉丝点击