oracle脏读如何解决,关于脏读分析

关于脏读分析

事实上,从目前的oracle的机制来看,Oracle是不支持脏读的,当事务A对某张表中的数据进行修改,并且尚没有Commit之前,若事务B去查询这张表的信息,看到的将是旧的数据,若此时事务B区对这张表的数据进行更新,会发现命令停在那里不执行下去了,产生了一个等待事件, 直到事务A进行Commit或者Rollback之后,事务B才会执行,这样做的目的就是为了保证数据的一致性。做个简单的测试如下,环境为oracle 10g:

1.新建测试表及插入数据

SQL> create table sonic_dirty_oracle (C1 varchar2(10));

Table created

SQL> insert into sonic_dirty_oracle values (‘AAA’);

1 row inserted

SQL> commit;

Commit complete

2.事务A做查询及更新操作(不提交)

SQL> select C1 from sonic_dirty_oracle;

C1

———-

AAA

SQL> update sonic_dirty_oracle set C1=’BBB’ where C1=’AAA’;

1 row updated

–这个时候没有Commit

SQL> select C1 from sonic_dirty_oracle;

C1

———-

BBB

3.事务B做查询、更新操作

SQL> select C1 from sonic_dirty_oracle;

C1

———-

AAA

SQL> update sonic_dirty_oracle set C1=’CCC’ where C1=’AAA’;此时事务B没能执行完成,停在那里不动

4.查询事务状态

SQL> select event,state from v$session where sid=’38’;

EVENT                                        STATE

————————————-    ——-

enq: TX – row lock contention    WAITING可见,事务A产生了一个TX Row Lock,只有等事务A做了Commit之后,事务B才会执行完这条命令

5.事务A提交后事务B才能正常完成

经过分析,系统不存在脏读现象,但存在另外一种现象,即事务A查询出结果后暂时停止操作,事务B对该条数据做删除操作,然后事务A对该条数据做修改操作,因为该条数据已经不存在,所以事务A的更新操作无法成功。解决办法:

1.在业务表中增加时间戳,记录上一次修改的时间,做更新前,把拿到的时间戳与最新数据的时间戳做比较,看是否一致,如果一致,证明是最新的记录,可进行操作;如果不一致,则需要重新获取最新的数据,进行相应操作。

2.在业务表中增加版本 字段,即记录修改次数。实现机制与1相同。

考虑到现有系统的并发性不是很大,且对相同数据进行操作的可能性非常小。修改

实现的成本和时间相对较高,代码的改动量非常大。目前阶段不予修改。如软件要做成

产品推广,这部分还是很有必要修改的。

相关资源:phantomjs-dirty:PhantomJS的脏兼容键值数据库-其它代码类资源…

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年3月5日
下一篇 2021年3月5日

相关推荐