`
touchmm
  • 浏览: 1043357 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

如果只提交一个查询,有必要用事务吗?

阅读更多

http://www.blogjava.net/terry-zj/archive/2005/12/06/22792.html

http://forum.javaeye.com/viewtopic.php?t=1603

但是并没有得出明确的结论。先让我们看看事务的定义:

引用:

Transactions are described in terms of ACID properties, which are as follows:
n Atomic: all changes to the database made in a transaction are rolled back if any
change fails.
n Consistent: the effects of a transaction take the database from one consistent
state to another consistent state.
n Isolated: the intermediate steps in a transaction are not visible to other users of
the database.
n Durable: when a transaction is completed (committed or rolled back), its effects
persist in the database.


即ACID的定义,从上面看来,似乎除了isolated之外,和只读查询都没有关系。那么是否只读查询不需要事务呢?

再看看Oracle对于只读事务的定义:

引用:
Read-Only Transactions
By default, Oracle guarantees statement-level read consistency. The set of data returned by a single query is consistent with respect to a single point in time. However, in some situations, you might also require transaction-level read consistency. This is the ability to run multiple queries within a single transaction, all of which are read-consistent with respect to the same point in time, so that queries in this transaction do not see the effects of intervening committed transactions.

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默认情况下保证了SQL语句级别的读一致性,即在该条SQL语句执行期间,它只会看到执行前点的数据状态,而不会看到执行期间数据被其他SQL改变的状态。

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

因此我们可以得出结论:

如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;
如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。


只读事务与读写事务区别

对于只读查询,可以指定事务类型为readonly,即只读事务。由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。

在JDBC中,指定只读事务的办法为:
connection.setReadOnly(true);

在Hibernate中,指定只读事务的办法为:
session.setFlushMode(FlushMode.NEVER);
此时,Hibernate也会为只读事务提供Session方面的一些优化手段

在Spring的Hibernate封装中,指定只读事务的办法为:
bean配置文件中,prop属性增加“readOnly”

我在MySQL4.1试验了一下,过程和结果如下:

数据库:MySQL4.1
表类型:InnoDB
Spring:1.1.2
Hibernate:2.1.7

使用Spring的声明式事务管理

试验过程如下:

不设置查询方法的事务类型(即不需要事务):访问查询页面,后台执行Spring的Bean方法,让Hibernate发送select语句,然后手工在MySQL里面修改该记录某字段值,再访问查询页面,发现被修改过的字段值并没有变化,Hibernate输出的log显示,数据库还是把老的字段值返回,而没有返回新的字段值。

设置查询方法的事务类型(只读事务):访问查询页面,后台执行Spring的Bean方法,让Hibernate发送select语句,然后手工在MySQL里面修改该记录某字段值,再访问查询页面,发现被修改过的字段值已经变化,Hibernate输出的log显示,数据库返回新的字段值。

这个试验说明,至少在MySQL4.1的InnoDB情况下,不使用只读事务的查询将无法读取到数据更新值,必须使用只读事务来保证读记录的数据一致性。这个结果非常令我诧异,和我预期完全两样。

我将在Oracle平台上试试看会有什么样的结果。

BTW: 如果MySQL的表类型改为MyISAM,那么即使不设置事务,也不会出现读数据不一致的现象。


oracle有两种方法保证在事务级读数据一致性(Transaction-Level Read Consistency)

一是用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE ,
当执行这条命令后读数据时会产生一些重复copy, 你也可以做数据修改, 但在大量数据修改的情况下容易造成deadlock或异常, 用commit或rollback将把ISOLATION LEVEL设回为缺省模式read committed,


二是用SET TRANSCATION READ ONLY
当执行这条命令时数据库会生成一个快照的latch, 这个latch会耗费一些resource, 如果你想进行数据修改会导致异常. 用commit或rollback会把latch释放掉, 也将把ISOLATION LEVEL设回为缺省模式read committed,

分享到:
评论

相关推荐

    关于SpringMyBatis纯注解事务不能提交的问题分析与解决

    ### 问题背景 在开发基于Spring框架的应用程序时,经常需要...此外,还需要注意事务管理器的正确配置,确保所有事务相关的组件都正确地引用了同一个数据源实例。通过上述方法,可以有效提升应用程序的可靠性和效率。

    44_了解分布式事务方案吗?你们都咋做的?有啥坑?.zip

    分布式事务是大型分布式系统中必不可少的一个技术环节,它旨在确保在多节点间的操作一致性,即使在面临网络延迟、节点故障等复杂情况时也能保持数据的完整性。本资料包提供了多种分布式事务解决方案的深入探讨,包括...

    atomikos分布式事务提交框架

    Atomikos是一个强大的开源分布式事务处理框架,专为Java企业级应用设计,它提供了一种在分布式环境中确保数据一致性的方式。在大型系统中,尤其是在微服务架构或云环境下的复杂业务场景,分布式事务处理是必不可少的...

    dataGridView事务提交

    在这个主题中,我们将深入探讨“dataGridView事务提交”这一概念,它涉及到Excel数据的导入、泛型集合Dictionary的使用以及事务处理来批量提交数据。以下是这些知识点的详细说明: 首先,Excel导入到dataGridView是...

    如何控制JPA的事务

    对于“R”查询,只是查询数据,没有对数据产生变化,所以并不需要控制事务。 JPA的事务管理可以通过配置文件(persistence.xml)中的“transaction-type”元素来指定事务类型。如果使用JTA管理事务,则配置代码如下...

    JAVA(Spring)事务管理.doc

    Spring定义了7种传播行为,例如PROPAGATION_REQUIRED表示如果当前没有事务,那么就在被调用的方法中新建一个,如果已经存在事务,则加入到当前事务中。PROPAGATION_REQUIRES_NEW则表示总是新建一个事务,如果当前...

    JDBC设置事务自动提交

    在默认情况下,JDBC连接处于自动提交模式,这意味着每当执行一个SQL语句时,如果成功,它就会被提交;如果出现错误,就会回滚。 要设置JDBC的自动提交模式,我们需要调用`Connection`对象的`setAutoCommit`方法。...

    使用事务实现更新多个数据表

    在没有事务的情况下,如果先更新一个表后出错,另一个表的更新已经完成,就会导致数据不一致。使用事务,我们可以确保这两个操作要么都成功,要么都不成功。 以下是使用SQL语句实现事务的步骤: 1. **开始事务**:...

    sqlserver中查找长时间未提交事务[总结].pdf

    拥有这些信息后,可以使用动态管理视图(DMV)来检验正在执行的 T-SQL,並在必要时关闭这个过程。 DBCC OPENTRAN 命令对孤立连接(在数据库中是打开的,但与应用程序或客户端已经断开的连接)是非常有用的,并能...

    分布式事务两阶段提交协议的实现方法研究.pdf

    分布式数据库系统中的数据分散在多个站点上,一个事务的执行可能需要涉及这些不同站点上的数据。因此,在分布式数据库系统中保证事务的ACID属性,特别是原子性和一致性,是实现过程中的一个关键问题。 文章提及的...

    Spring事务管理Demo

    - `REQUIRES_NEW`:总是新建一个事务,如果当前存在事务,则暂停当前事务。 - `NOT_SUPPORTED`:总是运行在非事务环境中,如果当前存在事务,则暂停事务。 - `NEVER`:总是运行在非事务环境中,如果当前存在事务,则...

    SpringBoot-Mybatis处理事务

    如果需要在非bean方法中使用事务,可以将这个方法包装到一个bean方法内,或者使用Spring AOP自定义切面来处理。 此外,SpringBoot还提供了对多数据源的支持,可以通过配置多个数据源并在需要的时候切换。对于复杂的...

    sql事务在ASP.Net mvc框架的使用.docx

    SQL事务在ASP.NET MVC框架中的使用 SQL事务是数据库管理系统中的一种机制,可以确保多个操作的原子性和一致性。在ASP.NET MVC框架中, ...我们通过一个示例代码展示了如何使用ADO.NET实现事务,以确保数据的一致性。

    数据库 事务

    数据库事务是数据库操作的核心概念,它是数据库管理系统执行过程中的一个逻辑工作单位,包含了对数据库的一系列操作。在数据库系统中,事务确保数据的一致性和完整性,使得即使在系统出现故障或者并发操作的情况下,...

    SQLServer存储过程中事务的使用方法

    这标志着事务的开始,所有的SQL操作将在同一个事务中执行,直到事务被提交或回滚。 ```sql begin transaction ``` 2. **执行SQL操作**:在开启事务后,执行一系列的SQL操作,如插入、更新或删除数据。这里以一个...

    WebSphere MQ与Oracle 数据库的XA事务(两阶段提交)实现

    当多个MQ队列参与同一个事务时,就需要使用到XA事务。在这种情况下,事务协调器(通常是MQ本身)负责协调所有参与队列,确保它们要么全部完成,要么全部回滚。这使得跨多个队列的操作具有原子性,是保证数据一致性的...

    事务传播特性&事务隔离级别

    7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按 TransactionDefinition.PROPAGATION_REQUIRED 属性执行。 事务隔离级别是指数据库事务的隔离级别,用于控制...

    spring声明事务,编程事务实现

    在 JDBC 中,每个 Connection 都带有一个事务,只是默认被设置为自动提交。一个连接可以有多个事务。在 Hibernate 中,事务是使用 Session 来处理的,而不是直接操作 JDBC。 Spring 声明事务提供了一种简洁、灵活的...

Global site tag (gtag.js) - Google Analytics