如果只提交一个查询,有必要用事务吗?这个问题之前已经讨论过http://forum./viewtopic.php?t=1603 但是并没有得出明确的结论。先让我们看看事务的定义: 引用: Transactions are described in terms of ACID properties, which are as follows:
再看看Oracle对于只读事务的定义: 引用: If you want to run a number of queries against multiple tables and if you are not doing any updating, you prefer a read-only transaction. After indicating that your transaction is read-only, you can run as many queries as you like against any table, knowing that the results of each query are consistent with respect to the same point in time.
而Oracle的只读查询(read-only transaction)则保证了事务级别的读一致性,即在该事务范围内执行的多条SQL都只会看到执行前点的数据状态,而不会看到事务期间的任何被其他SQL改变的状态。 因此我们可以得出结论: 如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;
对于只读查询,可以指定事务类型为readonly,即只读事务。由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。 在JDBC中,指定只读事务的办法为: 在Hibernate中,指定只读事务的办法为: 在Spring的Hibernate封装中,指定只读事务的办法为:
我在MySQL4.1试验了一下,过程和结果如下: 数据库:MySQL4.1 使用Spring的声明式事务管理 试验过程如下: 不设置查询方法的事务类型(即不需要事务):访问查询页面,后台执行Spring的Bean方法,让Hibernate发送select语句,然后手工在MySQL里面修改该记录某字段值,再访问查询页面,发现被修改过的字段值并没有变化,Hibernate输出的log显示,数据库还是把老的字段值返回,而没有返回新的字段值。 设置查询方法的事务类型(只读事务):访问查询页面,后台执行Spring的Bean方法,让Hibernate发送select语句,然后手工在MySQL里面修改该记录某字段值,再访问查询页面,发现被修改过的字段值已经变化,Hibernate输出的log显示,数据库返回新的字段值。 这个试验说明,至少在MySQL4.1的InnoDB情况下,不使用只读事务的查询将无法读取到数据更新值,必须使用只读事务来保证读记录的数据一致性。这个结果非常令我诧异,和我预期完全两样。 我将在Oracle平台上试试看会有什么样的结果。 BTW: 如果MySQL的表类型改为MyISAM,那么即使不设置事务,也不会出现读数据不一致的现象。
一是用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE ,
|
|
来自: web.anywhere > 《我的图书馆》