码迷,mamicode.com
首页 > 其他好文 > 详细

事务的四大特性

时间:2017-06-13 20:46:04      阅读:597      评论:0      收藏:0      [点我收藏+]

标签:level   glob   根据   不可重复读   增删改   查询   --   产生   线程并发   

  

事务的四大特性是事务本身具有的特点。简称ACID。

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency)
事务前后数据的完整性必须保持一致。

持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

隔离性(Isolation)
事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

由于事务的前三大特性数据库可以帮我们保证。需要讨论隔离性;

隔离性(Isolation)

 

  我们知道数据库的隔离性问题本质上就是多线程并发安全性问题。

  可以用锁来解决多线成并发安全问题,但是如果用了锁,必然会造成程序的性能大大的下降.对于数据库这种高并发要求的程序来说这是不可接受的.

  我们可以具体分析下隔离性产生的细节:

    如果两个线程并发修改,必然产生多线程并发安全问题,必须隔离开

    如果两个线程并发查询,必然没有问题,不需要隔离

    如果一个线程修改,一个线程查询,在不同的应用场景下有可能有问题,有可能没问题。

隔离性可能造成的问题:

 

  1.脏读:
    一个事务读取到另一个事务未提交的数据

  2.不可重复读:
    一个事务多次读取数据库中的同一条记录,多次查询的结果不同(一个事务读取到另一个事务已经提交的数据)

  3.虚读(幻读)
    有可能出现,有可能不出现:
      一个事务多次查询整表数据,多次查询时,由于有其他事务增删数据, 造成的查询结果不同(一个事务读取到另一个事务已经提交的数据)

数据库的隔离级别:

  1.查询数据库的隔离级别:select @@tx_isolation;

  2.修改数据库的隔离级别:  

    set [session/global] transaction isolation level xxxxxx;
    set global transaction isolation level serializable;
    不写默认就是session,修改的是当前客户端和服务器交互时是使用的隔离级别,并不会影响其他客户端的隔离级别
    如果写成global,修改的是数据库默认的隔离级别(即新开客户端时,默认的隔离级别),并不会修改当前客户端和已经开启的客户端的隔离级别

数据库中的锁:

  

  1. 共享锁
    共享锁和共享锁可以共存,共享锁和排他锁不能共存.在非Serializable隔离级别下做查询不加任何锁,在Serializable隔离级别下做查询加共享锁.
    案例演示:打开两个mysql客户端,将隔离级别都设置为Serializable级别,
    set session transaction isolation level Serializable;--设置后查询加了共享锁
    分别在两个客户端中查询:
    start transaction;
    select * from account;--都能查询出数据,说明共享锁可以共存。
  2. 排他锁
    排他锁和共享锁不能共存,排他锁和排他锁也不能共存,在任何隔离级别下做增删改都加排他锁.

  3.可能的死锁

    mysql可以自动检测到死锁,错误退出一方执行另一方

更新丢失问题:

  1. 更新丢失问题的产生
    两个并发的事务基于同一个查询结果进行修改,后提交的事务忽略了先提交的事务对数据库的影响,造成了先提交的事务对数据库的影响丢失,这个过程就叫做更新丢失

  2.更新丢失解决方案:

    将数据库设置为Serializable隔离级别,但是我们一般不会将数据库设置为Serializable。那么在非Serializable下又如何解决更新丢失?可以使用乐观锁、悲观锁。

    乐观锁和悲观锁并不是数据库中真实存在的锁,而是两种解决方案的名字。
      (1)悲观锁:
          在查询时,手动的加排他锁,从而在查询时就排除可能的更新丢失。
        select * from users for update;
      (2)乐观锁:
        在表中设计添加一个版本字段,在进行修改时,要求根据具体版本进行修改,
        并将版本字段+1,如果更新失败,说明更新丢失,需要重新进行更新。
        两种解决方案各有优缺点,如果查询多修改少,用乐观锁.
        如果修改多于查询,用悲观锁。

 

事务的四大特性

标签:level   glob   根据   不可重复读   增删改   查询   --   产生   线程并发   

原文地址:http://www.cnblogs.com/tongxuping/p/7003213.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!