写这篇文章的缘由,在于读过论坛中的一些帖子引发的疑问,先来看一下帖子的内容。
robbin的一个帖子
1. 首先最根本的,我们要看一下数据库中对于readonly事务的定义!
第一个帖子中已经给出了结论:
引用代码 Oracle默认情况下保证了SQL语句级别的读一致性,即在该条SQL语句执行期间,它只会看到执行前点的数据状态,而不会看到执行期间数据被其他SQL改变的状态。
而Oracle的只读查询(read-only transaction)则保证了事务级别的读一致性,即在该事务范围内执行的多条SQL都只会看到执行前点的数据状态,
而不会看到事务期间的任何被其他SQL改变的状态。
这个是Oracle对于只读事务的描述,要保证事务级别的读一致性有两种方式,第一个帖子中也给出了结论:
Java代码 一是用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
二是用SET TRANSCATION READ ONLY
我们来做一下测试(采用第二种方式):
编写一个oracle的存储过程:
Oracle存储过程代码 create or replace procedure p_test as
ware_code varchar2(14);
begin
set transaction read only;
select t.ware_code into ware_code from tp_area t where t.area_code = '1';
dbms_output.put_line(ware_code);
dbms_lock.sleep(10);--暂停10秒
select t.ware_code into ware_code from tp_area t where t.area_code = '1';
dbms_output.put_line(ware_code);
end p_test;
area_code是tp_area表的主键。在暂停的10秒钟内,我们去更改area_code为1的这条记录中ware_code的值,并提交。
经过测试发现,两次的输出结果一致,这就证明了正确性。
ps:对于oracle中只读事务的描述,推荐参考《Oracle 9i&10g编程艺术:深入数据库体系结构》这本书!
但是我们要说明,并不是所有的数据库都支持readonly事务。
2. 接下来我们讨论jdbc中对于readonly事务的描述
jdk1.6中java.sql.Connection接口中定义的方法
setReadOnly(boolean readOnly) throws SQLException的描述:将此连接设置为只读模式,作为驱动程序启用数据库优化的提示。
例如:此连接设置为只读模式后,通知Oracle后,Oracle做自己的优化;通知DB2后,DB2做自己的优化等等,但是并不一定对于数据库而言这就是readonly事务,此readonly并非彼readonly!
讲到这里&#