日期:2014-05-16  浏览次数:20473 次

隔离级别 总结

?

四个基本性质(ACID)

1.原子性(Atomicity)

事务中包含的操作要么全做要么全不做(all or none)。

?

2.一致性(consistency)

在事务开始以前数据处于一致性状态,事务结束后,数据也应处于一致性状态。

拿银行转账来说,一致性要求事务的执行不应该改变A、B两个账户的金额总和。如果没有这种一致性要求,转账过程中就会发生钱无中生有,或者不翼而飞的现象。事务应该把数据库从一个一致性状态转换到令一个一致性状态。

?

3.隔离性(isolation)

事务的隔离性要求系统必须保证事务不受其他并发执行的事务的影响,也既要达到这样的一个效果:对于任何一对事务T1和T2,对于T1来说,T2要么在T1之前执行,要么在T1之后执行。这样每个事务都感觉不到还有其他并行执行的事务的存在。

?

4.持久性(durability)

一个事务一旦完成,他对数据的改变必须是永久的。即使遇到故障也不会丢失,数据重要性决定了事务的持久性的重要性。

?

数据库的并发带来的问题

脏读

第二个事务读取到第一个事务尚未确认的数据。

1、事务A将数据x从原来的1000修改成2000

2、事务B在事务A未提交时,读到了x是2000

3、事务A回滚,最终x恢复成1000

最终x的正确值应是1000,而事务B读到了错误的x=2000的值

示例

1、Mary的工资是1000,财务把many的工资修改成了2000。

2、Mary查看自己的工资时发现时2000,非常高兴。

3、财务发现Mary的工资录入错误,立即又改回了1000。

Mary查询到自己的工资是2000就是脏数据,最终她是拿不到那么多的钱的。

?

不可重复读

一个事务在两次查询中得到的结果不一致。

1、事务A查询x的值是1000,事务未结束

2、事务B将x修改成2000

3、事务A再次查询x时,变成了2000

示例

1、Mary查询自己的工资是1000,操作尚未完成

2、财务将Mary修改成2000

3、当Mary再次查询自己的工资时发现变成了2000

?

幻象读

一个事务两次查询到的记录数量不相同

1、事务A统计出x=1000的记录数是10条,事务未结束

2、事务B向数据库中插入了一条x=1000的记录

3、事务A再次统计时发现x=1000的记录数变成了11条

示例

1、Mary查询自己2011年的工资条是10个(截止到10月,11月的工资还未发放)

2、财务正好录入了Mary的11月的工资条

3、当Mary再查询自己2011年的工资条时发现变成了11个,感到莫名其妙

?

?

设置和查看全局事务隔离级别(MySQL)

mysql默认隔离级别是Repeatable Read

SELECT @@global.tx_isolation;
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

?

设置和查看session事务隔离级别

SELECT @@session.tx_isolation;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

?

设置和查看全局autocommit标记

SELECT @@global.autocommit;
SET GLOBAL autocommit = off / on;

?

?