有一个线程设置值需要的时间为两秒钟,第二个线程拿值需要一秒钟,这样就可能出现脏读
代码如下:
package qun.com;
/**
* 有一个线程设置值需要的时间为两秒钟,第二个线程拿值需要一秒钟,这样就可能出现脏读
* 所以在setvalue 和getvalue上都加上锁 这是同一把锁 第二个线程只能排队
* oracle数据库有一致性读的特性,如果在某个时间发起的读请求,拿到的一定是那个时间点的数据 不管是否之后有修改
* undo,客户端执行dml语句,oracle都会将老的值放在undo中,类似于备份 这就是回滚的概念
* 如果查询的过程中 数据发生修改,查询线程会去查询时间点获取undo存储的老值,如果获取不到 会抛异常snapshottooold
*/
public class DirtyRead {
private String username = "qun";
private String password = "123456";
public synchronized void setValue(String username ,String password) {
this.username = username;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.password = password;
System.out.println("setValue最终结果 username = "+username +" password = "+password);
}
//保证不脏读,需要加上synchronized
private void getValue() {
System.err.println("getValue得到结果 username = "+this.username +" password = "+this.password);
}
public static void main(String[] args) throws InterruptedException {
DirtyRead dr = new DirtyRead();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
dr.setValue("z", "z789");
}
});
t1.start();
Thread.sleep(1000);
dr.getValue();
}
}