您的位置:首页 > 其它

事务特性和隔离级别

2017-01-18 20:36 302 查看


MySQL中的事务

事务是DBMS中的执行单位,它是有限的数据库操作序列组成的。但是并不是所有的数据库操作序列都能成为事务。一般说来,事务具有如下4个特性(ACID特性):

1、原子性(Automicity):该特性引起的数据库操作”要么全部执行,要么全部不执行”。

2、一致性(Consistency):该特性表示数据库操作之前和操作之后的最终状态是一致的。比如,两个用户a,b之间相互转账,但是最终两个用户的总金额是不变的。

3、隔离性(Isolation):多个事务并发执行时,各个事务独立执行,且各个事务之间的影响最小。

4、持久性(Durability):一旦事务提交执行成功,则系统保证在任何故障下,事务都不会引起不一致性。

 

 


丢失更新:两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,这是由于没有加锁造成的;

 

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

 e.g.

        1.Mary的原工资为1000, 财务人员将Mary的工资改为了8000(但未提交事务)

        2.Mary读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!

        3.而财务发现操作有误,回滚了事务,Mary的工资又变为了1000

          像这样,Mary记取的工资数8000是一个脏数据。

 

2. 不可重复读 :是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

    e.g.

    1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成

    2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.

    3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000

 解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

 

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

   e.g. 

   目前工资为1000的员工有10人。

   1.事务1,读取所有工资为1000的员工。

   2.这时事务2向employee表插入了一条员工记录,工资也为1000

   3.事务1再次读取所有工资为1000的员工 共读取到了11条记录, 

 

 解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题

 

 

MySQL中隔离级别分为4种:

1、Read-Uncommited:读未提交。该隔离级别下的当前事务可以看到其他未提交事务的执行结果。在该级别下会出现脏读现象。

2、Read-Committed:读提交。解决了脏读的问题。在该隔离级别下,当前事务只能看到其他事务提交后的执行结果。因此该隔离级别支持不可重复读。大多数数据库的的默认隔离级别为Read-Committed,但是MySQL不是的。

3、Repeatable-Read:重复读。解决了不可重复读的问题。在该级别且当前事务没有提交的前提下,不管其他事务如何修改数据,每次查询的结果都是一样的。一旦当前事务提交,则查询的结果就是最新的结果。因此会出现幻读的现象。事务提交前和提交后的结果不一样。在该级别下,为了提高并发能力,需要借助MVCC(多版本并发控制)机制来完成。这是MySQL的默认隔离级别。

4、Serializable:可串行化。就是事务接着一个一个的串行执行,只有同一个实例下的其他事务结束后,才可以执行同一个实例下的另一个事务。这样就解决了幻读的问题。

 

总结:MySQL的四种默认隔离级别所出现的读取方式:

1、Read-Uncommitted:会出现脏读、不可重复读等现象。

2、Read-Committed:会出现不可重复现象。

3、Repeatable-Read:会出现幻读现象。

4、Serializable:不会出现脏读、不可重复读、幻读等现象。

 

由此可见,隔离级别越高,所受到的干扰越小,消耗系统的资源越多。且最重要的是它们的并发性能越差。

 

 MySQL处理事务由2种方法:

1、手动执行事务

        MySQL>begin; 或MySQL>start 
transaction;   ##表示启动事务

        MySQL>rollback;                                           ##撤销之前所做的修改(回滚)

        MySQL>commit;                                               ##提交事务

 

2、设置事务的自动提交模式

        MySQL>select @@autocommit;     ##查看当前事务是否是自动提交的。0或off表示关闭自动提交;1或on表示开启自动提交

        set  autocommit=0    ##关闭自动提交功能(只能用于当前会话,这是修改的会话变量)

        set  autocommit=1    ##开启自动提交功能(只能用于当前会话,这是修改的会话变量)

 

MySQL中隔离级别的设定:

MySQL>select @@tx_isolation;        ##显示当前的隔离级别

MySQL>set  tx_isolation=‘VALUE‘   ##用来设定隔离级别

 

 

事务的执行状态:共有5种状态

1、active:表示当前事务正在进行当中

2、部分提交的:表示语句在执行过程中,由于某种原因(如宕机)导致只执行了一部分。因此事务就处于该状态下。

3、失败:表示事务没有执行成功。

4、终止:由于事务执行失败,因此系统会终止该事务

5、提交成功:表示提交后,事务执行成功。



参考
http://uule.iteye.com/blog/1109647 http://codecloud.net/33550.html http://www.cnblogs.com/549294286/p/5433318.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息