`

事务隔离级别

阅读更多

事务隔离级别

事务隔离级别就是加锁的几种方案:数据库中的锁有:更新锁,....很多.

1 四大隔离级别 

  事务隔离级别是用来处理与事务并发相关的问题!你可以想象一下,两个人同时对同一个银行账户进行操作是什么结果。

 

隔离级别

脏读

不可重复读

虚读

第一类丢失更新

第二类丢失更新

READ UNCOMMITTED

允许

允许

允许

不允许

允许

READ COMMITTED

不允许

允许

允许

不允许

允许

REPEATABLE READ

不允许

不允许

允许

不允许

不允许

SERIALIZABLE

不允许

不允许

不允许

不允许

不允许

 

2 五大并发事务问题

因为并发事务导致的问题大致有5类,其中两类是更新问题,三类是读问题。

 

脏读(dirty read):读到未提交更新数据

现在为止:所有的数据库都不允许脏读操作.

 

时间

转账事务A

取款事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额为1000

T4

 

取出500元把余额改为500

T5

查看账户余额为500元(脏读)

 

T6

 

撤销事务,余额恢复为1000

T7

汇入100元把余额改为600

 

T8

提交事务

 

  

A事务查询到了B事务未提交的更新数据,A事务依据这个查询结果继续执行相关操作。但是接着B事务撤销了所做的更新,这会导致A事务操作的是脏数据。(这是绝对不允许出现的事情)

 

虚读(phantom read(有人称之为幻读)读到已提交插入数据

 

时间

统计金额事务A

转账事务B

T1

 

开始事务

T2

开始事务

 

T3

统计总存款数为10000

 

T4

 

新增一个存款账户,存款为100

T5

 

提交事务

T6

再次统计总存款数为10100

 

 

  A事务第一次查询时,没有问题,第二次查询时查到了B事务已提交的新插入数据,这导致两次查询结果不同。(在实际开发中,很少会对相同数据进行两次查询,所以可以考虑是否允许虚读)

 

不可重复读(unrepeatable read):读到已提交更新数据

 

时间

取款事务A

转账事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额为1000

T4

查询账户余额为1000

 

T5

 

取出100元,把余额改为900

T6

 

提交事务

T7

查询账户余额为900元(与T4读取的一不一致)

 

 

  不可重复读与虚读有些相似,都是两次查询的结果不同。后者是查询到了另一个事务已提交的新插入数据,而前者是查询到了另一个事务已提交的更新数据。

 

第一类丢失更新:撤销了已提交数据

 

时间

取款事务A

转账事务B

T1

开始事务

 

T2

 

开始事务

T3

查询账户余额为1000

 

T4

 

查询账户余额为1000

T5

 

汇入100元把余额改为1100

T6

 

提交事务

T7

取出100元把余额改为900

 

T8

撤销事务

 

T9

余额恢复为1000

 

 

这种并发问题是由于完全没有隔离事务造成的。当两个事务更新相同的数据时,如果一个事务被提交,另一个事务却撤销,那么会连同第一个事务所做的更新也被撤销了。(这是绝对不允许出现的事情) 事务A的开始时间和结束时间包含事务B的开始和结束时间,事务A回滚事务的同时,B的已经提交的事务也回滚的,这是不允许的,这就是第一类丢失更新.

 

第二类丢失更新:提交覆盖已提交事务

 

时间

取款事务A

转账事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额为1000

T4

查询账户余额为1000

 

T5

 

取出100元把余额改为900

T6

 

提交事务

T7

汇入100

 

T8

提交事务

 

T9

余额恢复为1100

 

 

  这是在实际应用中经常遇到的并发问题,它和不可重复读本质上是同一类并发问题,通常把它看做是不可重复读的一个特例。两个或多个事务查询同一数据。然后都基于自己的查询结果更新数据,这时会造成最后一个提交的更新事务,将覆盖其它已经提交的更新事务。

并行化:多个事务,同进行操作,效率高,但非常不安全.

串行化:多个事务,一个一个进行处理,排队.非常安全但效率很低.

3 哪种隔离级别最好

4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。

 

1 SERIALIZABLE(串行化)

当数据库系统使用SERIALIZABLE隔离级别时,一个事务在执行过程中完全看不到其他事务对数据库所做的更新。当两个事务同时操作数据库中相同数据时,如果第一个事务已经在访问该数据,第二个事务只能停下来等待,必须等到第一个事务结束后才能恢复运行。因此这两个事务实际上是串行化方式运行。

 

2 REPEATABLE READ(可重复读)

当数据库系统使用REPEATABLE READ隔离级别时,一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事务对已有记录的更新。

 

3 READ COMMITTED(读已提交数据)

  当数据库系统使用READ COMMITTED隔离级别时,一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且还能看到其他事务已经提交的对已有记录的更新。

 

4 READ UNCOMMITTED(读未提交数据)

  当数据库系统使用READ UNCOMMITTED隔离级别时,一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且还能看到其他事务没有提交的对已有记录的更新。

 

你可能会说,选择SERIALIZABLE,因为它最安全!没错,它是最安全,但它也是最慢的!四种隔离级别的安全性与性能成反比!最安全的性能最差,最不安全的性能最好!

<!--EndFragment-->
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics