数据库事务及MySQL InnoDB 事务

数据库事务及MySQL InnoDB 事务

 

事务的四个特性

1. 原子性:要不全做,要不全不做

2. 一致性:数据库从一种状态转变为下一种一致的状态

3. 隔离性:一个事务的执行不会被另一个事务干扰

4. 持久性:事务一旦提交,结果就会被持久化到数据库

 

 

事务的实现

1. 隔离性通过Mysql InnoDB锁就可以实现,

2. 原子性、一致性、持久性通过数据库的redo和undo来完成

 

 

Undo Log

原理:

1. 为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方undo表空间。

2. 然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用UndoLog中的备份将数据恢复到事务开始之前的状态。

3. 除了可以保证事务的原子性,Undo Log也可以用来辅助完成事务的持久化。

 

Undo Log实现原子性和持久化的事务的简化过程

假设有A、B两个数据,值分别为1,2。

A.事务开始.

B.记录A=1到undolog.

C.修改A=3.

D.记录B=2到undolog.

E.修改B=4.

F.将undolog写到磁盘。

G.将数据写到磁盘。

H.事务提交

 

Undo Log能同时保证原子性和持久性,有以下特点:

1. 更新记录前,记录undo log

2. 为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化

3. Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃,undo log是完整的,可以用来回滚事务

4. 如果在A-F之间系统崩溃,因为数据没有持久化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态

 

缺陷:

每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。

 

解决方法:

如果能够将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一种机制来实现持久化,即Redo Log

 

Redo log,记录的是新数据的备份。

原理:

1. 在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。

2. 当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据RedoLog的内容,将所有数据恢复到最新的状态。

 

Undo+Redo

事务的简化过程,假设有A、B两个数据,值分别为1,2.

A.事务开始.

B.记录A=1到undolog.

C.修改A=3.

D.记录A=3到redolog.

E.记录B=2到undolog.

F.修改B=4.

G.记录B=4到redolog.

H.将redolog写入磁盘。

I.事务提交

 

Undo+Redo事务的特点:

1. 为了保证持久性,必须在事务提交前将RedoLog持久化。

2. 数据不需要在事务提交前写入磁盘,而是缓存在内存中。

3. RedoLog保证事务的持久性。

4. UndoLog保证事务的原子性。

5. 有一个隐含的特点,数据必须要晚于redolog写入持久存

 

 

Undo log 和 Redo log的区别:

理解一:

Redo log:重做日志

Undo log:撤销日志

1. 重做日志:每当有操作执行前,将数据真正更改时,先前相关操作写入重做日志。这样当断电,或者一些意外,导致后续任务无法完成时,系统恢复后,可以继续完成这些更改

2. 撤消日志:当一些更改在执行一半时,发生意外,而无法完成,则可以根据撤消日志恢复到更改之前的壮态

 

理解二:

redo:每次操作都先记录到redo日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件

undo:记录更改前的一份copy,但你系统rollback时,把这份copy重新覆盖到原来的数据

 

理解三:

redo:记录所有操作,用于恢复

undo:记录所有的前印象,用于回滚

 

一个实例表现这两个日志代表的概念:前滚与回退

比如某一时刻数据库DOWN机了,有两个事务,一个事务已经提交,另一个事务正在处理,数据库重启的时候就要根据日志进行前滚及回退,把已提交事务的更改写到数据文件,未提交事务的更改恢复到事务开始前的状态。

 

 

MySQL的读数据问题

1. 脏读:一个事务读取了另一个事务未提交的数据,而这个数据有可能回滚

2. 不可重复读:在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。

例如:事务B中对某个查询执行两次,当第一次执行完时,事务A对其数据进行了修改。事务B中再次查询时,数据发生了改变

3. 幻读:当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

事务隔离级别

1.READ UNCOMMITTED

常被成为Dirty Reads(脏读),可以说是事务上的最低隔离级别:在普通的非锁定模式下SELECT的执行使我们看到的数据可能并不是查询发起时间点的数据,因而在这个隔离度下是非Consistent Reads(一致性读);

2.READ COMMITTED

这一隔离级别下,不会出现DirtyRead,但是可能出现Non-RepeatableReads(不可重复读)和PhantomReads(幻读)。

3. REPEATABLE READ

REPEATABLE READ隔离级别是InnoDB默认的事务隔离级。在REPEATABLE READ隔离级别下,不会出现DirtyReads,也不会出现Non-Repeatable Read,但是仍然存在PhantomReads的可能性。

4.SERIALIZABLE

SERIALIZABLE隔离级别是标准事务隔离级别中的最高级别。设置为SERIALIZABLE隔离级别之后,在事务中的任何时候所看到的数据都是事务启动时刻的状态,不论在这期间有没有其他事务已经修改了某些数据并提交。所以,SERIALIZABLE事务隔离级别下,PhantomReads也不会出现。

 

参考:

http://xuebinbin212.blog.163.com/blog/static/1121673762013921111828684/

http://www.cnblogs.com/luxiaoxun/p/4694144.html

http://www.cnblogs.com/flysun0311/archive/2013/03/11/2953883.html

猜你喜欢

转载自youyu4.iteye.com/blog/2342080