原文地址: http://boy00fly.iteye.com/blog/1142754

我们要看一下Oracle数据库中对于readonly事务的定义!

  1. Oracle默认情况下保证了SQL语句级别的读一致性,即在该条SQL语句执行期间,它只会看到执行前点的数据状态,而不会看到执行期间数据被其他SQL改变的状态。
  2. 而Oracle的只读查询(read-only transaction)则保证了事务级别的读一致性,即在该事务范围内执行的多条SQL都只会看到执行前点的数据状态,
  3. 而不会看到事务期间的任何被其他SQL改变的状态。

这个是Oracle对于只读事务的描述,要保证事务级别的读一致性有两种方式:

  1. 一是用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
  2. 二是用SET TRANSCATION READ ONLY

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!

1. 首先jdbc的规范中已经说明了readonly只是 将此连接设置为只读模式,作为驱动程序启用数据库优化的提示,并不一定以只读事务执行!

2. 对于oracle的jdbc驱动而言,不同版本的驱动对readonly的支持也不一样!


“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,

那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。

不同数据库的JDBC驱动,有的支持readonly事务,有的不支持。

@Transactional(readOnly = true)   ( Spring的 readOnly属性是否起作用取决于数据库是否支持,oralce是支持的)