一、参见hibernate的api

http://tool.oschina.net/apidocs/apidoc?api=hibernate-3.6.10

http://tool.oschina.net/apidocs/apidoc?api=hibernate-4.1.4

说明:贴出两个版本的原因在于FlushMode属性在3.6与4.1版本的设置有所不同,3.6的FlushMode属性是一个Class类,而4.1已更换了Enum。

二、 FlushMode属性(策略)

在org.hibernate Class FlushMode中这样解释它的作用:Represents a flushing strategy. The flush process synchronizes database state with session state by detecting state changes and executing SQL statements.

代表一个flushing(刷新)的策略,它将通过改变session的状态和执行SQL的状态来处理线程中的数据。

NEVER 已被MANUAL取代

ALWAYS在查询前刷新Session

AUTO 在确保查询从不会返回脏数据的情况下,在查询前刷新Session

COMMITSession在提交事务时刷新。

MANUALSession永远只会在应用程序调用Session.flush()方法时才会刷新。

说明:

1. Session:Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存、更新、删除和查询方法。它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新数据库。根据Session的定义,可以知道刷新Session也就刷新了数据库。

2.调用Session.flush()方法,不管FlushMode被设置成任何策略,均会将刷新Session,使其中的缓存数据同步至数据库。

3.ALWAYSAUTO的区别:从API看出,AUTO的解释Session刷新较ALWAYS多了一个“sometimes ”,说明AUTO并不会像ALWAYS那样总是刷新Session,那它在何时才会刷新呢?当hibernate缓存中的对象被改动之后,会被标记为脏数据(即与数据库不同步了)。当 session设置为FlushMode.AUTO时,hibernate在进行查询的时候会判断缓存中的数据是否为脏数据,是则刷数据库,不是则不刷,而always是直接刷新,不进行任何判断。很显然auto比always要高效得多。

4.设置FlushMode.MANUAL,在操作过程中hibernate会将事务设置为readonly,所以在增加、删除或修改操作过程中会出现如下错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

解决方式见“附:解决因FlushMode设置出现不能进行增、删、改的异常”

用表格形式表示如下:

表1

Session的刷新策略

调用Session的查询方法时

调用Session.commit()时

调用Session.flush()时

ALWAYS

刷新

刷新

刷新

AUTO

当缓存被标记为脏数据时,刷新

刷新

刷新

COMMIT

不刷新

刷新

刷新

MANUAL

不刷新

不刷新

刷新

三、小结:FlushMode的4个属性实际上代表了Hibernate处理Session中的持久化对象的缓存的4种策略,这4种策略最大的不同就是刷新Session,将其中的缓存的持久化对象同步更新数据库的时间点不同。

四、OpenSessionInViewFilter的FlushMode属性设置与transaction(spring注入的事务)的关系:假设在OpenSessionInViewFilter设置FlushMode.MANUAL若OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.MANUAL。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再解除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.MANUAL。所以受transaction保护的方法有写权限,没受保护的则没有。

附:解决因FlushMode设置出现不能进行增、删、改的异常

1.配置事务,spring会读取事务中的各种配置来覆盖hibernate的session中的FlushMode。此种情况下,即使在FlushMode设置MANUAL也没有关系(这并意味OpenSessionInViewFilter的FlushMode属性可以随意设置,这得依据实际需求,具体参见第四点--OpenSessionInViewFilter的FlushMode属性设置与transaction(spring注入的事务)的关系)。

例:

<bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <aop:config>
        <aop:pointcut id="managerOperation"
            expression="execution(* com.test.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="managerOperation" />
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*"  propagation="REQUIRED" read-only="true" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="add*"  propagation="REQUIRED" />
            <tx:method name="del*"  propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" isolation="REPEATABLE_READ"/>
        </tx:attributes>
    </tx:advice>  
2.直接修改opensessioninviewfilter过滤器的配置,配置过滤器的时候置 openSession org.springframework.orm.hibernate3.support.OpenSessionInViewFilter中 flushMode为AUTO/COMMIT 。注意:如果这样设置,则要么结合1,要么结合3,因为不管怎样,对于Hibernate来说总是要配置事务,否则无法操作持久化对象同步至数据库。

例:

<filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>flushMode</param-name>
            <param-value>AUTO</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.先编程式修改FlushMode,比如session.setFlushMode(FlushMode.AUTO);

例:

@Override
    public void saveOrUpdate(T t) {
        Session session = null;
        Transaction tr = null;
        try {
            session = HibernateSessionFactory.getSession();
            tr = session.beginTransaction();
            session.saveOrUpdate(t);
            tr.commit();
            HibernateSessionFactory.closeSesssion();
        } catch (Exception e) {
            e.printStackTrace();
            tr.rollback();
        }
    }

鸣谢:http://blog.csdn.net/accpsz/article/details/6010618

http://blog.csdn.net/looyo/article/details/6309136

FlushMode属性与transaction(spring注入的事务)的更多相关文章

  1. Spring注入JPA+JPA事务管理

    本例实现的是Spring注入JPA 和 使用JPA事务管理.JPA是sun公司开发的一项新的规范标准.在本质上来说,JPA可以看作是Hibernate的一个子集:然而从功能上来说,Hibernate是 ...

  2. Spring 声明式事务,propagation属性列表及isolation(隔离级别)

    Spring 声明式事务,propagation属性列表 TransactionDefinition接口中定义,共有7种选项可用: PROPAGATION_REQUIRED:支持当前事务,如果当前没有 ...

  3. SPRING事务的属性有哪些?其中,事务隔离级别有哪几种?什么情况需要使用这几种事务隔离级别?

    Spring 声明式事务,propagation属性列表  PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择.  PROPAGATION_SU ...

  4. Spring提取@Transactional事务注解的源码解析

    声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记: 难免有错误,敬请读者谅解!!! 1.事务注解标签 <tx:annotation-driven /> 2.tx 命名空间 ...

  5. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  6. Spring声明式事务管理基于@Transactional注解

    概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解.         第一种方式我已在上文为大 ...

  7. Spring管理 hibernate 事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,DataSource.TransactionManager和代理机制这三部分,无论是那种配置方法,一般变化的只是代理机制这块! 首先我创建了两个类 ...

  8. Spring学习8-Spring事务管理(AOP/声明式式事务管理)

    一.基础知识普及 声明式事务的事务属性: 一:传播行为 二:隔离级别 三:只读提示 四:事务超时间隔 五:异常:指定除去RuntimeException其他回滚异常.  传播行为: 所谓事务的传播行为 ...

  9. Spring学习8-Spring事务管理(编程式事务管理)

    一.Spring事务的相关知识   1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一 ...

随机推荐

  1. Cesium原理篇:GroundPrimitive

    今天来看看GroundPrimitive,选择GroundPrimitive有三个目的:1 了解GroundPrimitive和Primitive的区别和关系 2 createGeometry的特殊处 ...

  2. [搬砖]Pycharm中启动IPython notebook失败提示load_entry_point ImportError: Entry point (&#39;console_scripts&#39;, &#39;ipython&#39;) not found的解决方法

    前提:直接运行ipython正常,“which -a ipython”命令显示也只有一个ipython存在,在ipynb文件中点运行启动notebook时提示错误类似如下: Traceback (mo ...

  3. 关于“float”的一次探索--遇到了一个span元素可以设置宽高引发的思考

    起初,这个问题和float还有设置宽高之间是没有任何关联的,一开始这是一个关于height和line-height的问题,目的是为了探究一下这两者之间的关系,但是在学习的过程中,我翻之前写的代码,发现 ...

  4. mysql下载安装

    1.下载 下载地址:http://dev.mysql.com/downloads/mysql/ 根据电脑配置来选,我选了 windows(x86,64-bit),ZIP Archive这个,点击Dow ...

  5. 如何查看设备的 UDID

    手机连接上电脑,打开 Xcode,确认手机已连上: command+shift+2,就可以查看到 UDID 了:

  6. 上线踩坑引发的处理方式---lsof,strace

    两个跟踪进程的linux命令 lsof -p pidstrace -p pid快速跟踪进程出现问题的地方.由于进程本身运行良好,但是内部一直等待第三方哪个应答,导致进程假死.引用自:http://li ...

  7. 扩展SharePoint链接字段

    默认SharePoint中的链接字段有很多限制,例如 输入文字的时候只能录入255个字符 链接显示的是文字 点击链接后只能在当前页面打开链接 - - - - - - -- - - - - - -   ...

  8. Linux学习书目

    Linux基础 1.<Linux与Unix Shell 编程指南> C语言基础 1.<C Primer Plus,5th Edition>[美]Stephen Prata著 2 ...

  9. [转]Eclipse遇到的常见问题

    1.  提示:“Setting build path” has encountered a problem,Could not write file D:\\workspace\demo\.class ...

  10. Nmap扫描教程之DNS服务类

    Nmap扫描教程之DNS服务类 Nmap DNS服务类 DNS(Domain Name System,域名系统)的作用就是将主机名解析为相应IP地址的过程. 通常主机域名的一般结构为:主机名.三级域名 ...