开发者社区> 山月风成> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 脏读 脏读:在业务中读取的数据出现不一致的错误。 package demo; /* 脏读:数据不一致的错误。
+关注继续查看

脏读

  • 脏读:在业务中读取的数据出现不一致的错误。
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:----123
There set UserName : Jack---password:----123456

getUser方法加上synchronized时:结果
There set UserName : Jack---password:----123456
There 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,这就是关系型数据库的一致性表示。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
婚恋交友源码,围绕数据一致性问题的思考
婚恋交友源码,围绕数据一致性问题的思考
20 0
缓存和数据库的数据同步和一致性
首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。
94 0
深入理解 ZK集群如何保证数据一致性(一)
深入理解 ZK集群如何保证数据一致性(一)
158 0
突破Java面试(27)-如何保证缓存与数据库的数据一致性
1 面试题 如何保证缓存与数据库的双写一致性? 2 考点分析 你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 3 详解 一般来说,就是如果你的系统不是严格要求缓存+数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要做这个方案 读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况 串行化之后,就会导致系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支撑线上的一个请求。
8895 0
spring 多数据源一致性事务方案
spring 多数据源配置 spring 多数据源配置一般有两种方案: 1、在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory。在dao 层根据不同业务自行选择使用哪个数据源的session来操作。
1839 0
一次数据库宕机问题的分析
今天来到办公室,发现有一台服务器中的数据库实例停掉了。这种情况真是意料之外,尤其是我还不是很熟悉这台机器的服务。 赶紧查看数据库日志,可以看到数据库在昨晚停掉了,从日志来看没有人为的痕迹。
1330 0
+关注
山月风成
君子不以辞尽人,故天下有道,则行有枝叶;天下无道,则辞有枝叶。热爱技术岗位,因为这里单纯友好,自由和分享。
37
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载