脏读和数据库一致性的分析

来源:互联网 发布:linux网吧视频服务器 编辑:程序博客网 时间:2024/06/07 00:15

脏读

  • 脏读:在业务中读取的数据出现不一致的错误。
package demo;/* 脏读:数据不一致的错误。 *  *  在对一个对象的方法加锁的时候,需要考虑业务的整体性, *  在demo中为setUser/getUser方法同时加锁synchronized同步关键字, *  保证业务的原子性,不然会出现业务错误。 * */public class DirtyRead {    private String userName = "lc";    private String password = "123";    //设置User的名、密码    public synchronized void setUser(String userName, String password){        this.userName = userName;        try {            Thread.sleep(3000);        } catch (Exception e) {            e.printStackTrace();        }        this.password = password;        System.out.println("There set UserName : "+userName +"---password:----"+password);    }    //得到User信息    public synchronized void getUser(){        System.out.println("There get UserName : "+userName +"---password:----"+password);    }    //test    public static void main(String[] args) throws InterruptedException {        final DirtyRead dr1 = new DirtyRead();        Thread t1 = new Thread(new Runnable() {            @Override            public void run() {                dr1.setUser("Jack", "123456");            }        });        /*         * t1线程只休眠等待1s,但是在setUser方法中,有Thread.sleep(3000);等待3秒。         * 也就是说,在set方法还没有执行完,主线程就开始调用getUser方法。         * 这样就造成了数据的不一致性,脏读         * */        t1.start();        t1.sleep(1000);        dr1.getUser();    }}getUser方法没有加synchronized时:结果There get UserName : Jack---password:----123There set UserName : Jack---password:----123456getUser方法加上synchronized时:结果There set UserName : Jack---password:----123456There get UserName : Jack---password:----123456

关系型数据库中的一致性表现

  • 我们常说的ACID:原子性、一致性、隔离性、永久性
场景描述:一个用户A在9:00访问数据库表table。查询一个数据num=100,假设table数据量1000W,需要10分钟才能查询到num,然后一个用户B , 在905访问数据库,对数据num进行Update,num=200。问:用户A查询到的数据num的值,是100还是200
  • 用户A在9:00发起的查询,他查询到的数据永远只是9:00这一刻数据库的数据,所以是num=100,
  • 为什么?
比如说Oracle数据库中有个Undo的概念,类似于日志,记录修改数据的旧值。A——9:00发起查询,在9:10查到num=?B在905提交update了num=200。A在查到num的值的时候,发现num有更改过,数据库就去Undo中找旧值返给A。就旧值返给A,即使没有,报一个异常snapshot too  old的异常。数据库让它报异常都不会将num=200返回给A,这就是关系型数据库的一致性表示。