脏读
package demo;
public class DirtyRead {
private String userName = "lc";
private String password = "123";
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);
}
public synchronized void getUser(){
System.out.println("There get UserName : "+userName +"---password:----"+password);
}
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.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 , 在9:05访问数据库,对数据num进行Update,num=200。
问:用户A查询到的数据num的值,是100还是200?
- 用户A在9:00发起的查询,他查询到的数据永远只是9:00这一刻数据库的数据,所以是num=100,
- 为什么?
比如说Oracle数据库中有个Undo的概念,类似于日志,记录修改数据的旧值。
A——9:00发起查询,在9:10查到num=?
B在9:05提交update了num=200。
A在查到num的值的时候,发现num有更改过,数据库就去Undo中找旧值返给A。
就旧值返给A,即使没有,报一个异常snapshot too old的异常。
数据库让它报异常都不会将num=200返回给A,这就是关系型数据库的一致性表示。