一、参见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。

COMMIT:Session在提交事务时刷新。

MANUAL:Session永远只会在应用程序调用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);

例:

@Overridepublic 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

转载于:https://www.cnblogs.com/wql025/p/4822791.html

FlushMode属性与transaction(spring注入的事务)相关推荐

  1. 事务 | Spring Cloud 分布式事务管理(二)2pc/3pc

    Spring Cloud 分布式事务管理(二)2pc/3pc 上一篇 Spring Cloud 分布式事务管理 上一章,讲到了微服务带来的优点和缺点以及分布式事务的不确定性.这节说一下2pc/3pc ...

  2. spring事务(Transaction)的七种事务传播行为及五种隔离级别

    1. 首先,说说什么事务(Transaction) 事务,就是一组操作数据库的动作集合.事务是现代数据库理论中的核心概念之一. 如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事 ...

  3. quartz的job类无法保留本身通过spring注入的属性问题

    现在有一个应用需要定时做一些动作,使用的是quartz+spring,但是没有使用spring实现的quartz,这里发现了一个问题,就是通过spring注入进来的bean用于做为quartz的job ...

  4. Spring框架中集合属性为对象的注入方法

    Spring框架中集合属性为对象的注入方法 前言 创建基础类 创建`Course`类 编写XML配置文件 创建测试类 执行结果 前言 在集合的属性注入中,如果注入属性为普通类型(String.int) ...

  5. spring学习---IOC--基于xml--bean管理--spring创建对象--spring注入属性--其他属性注入--外部bean--内部bean

    基于xml配置以下 bean管理 实现两种操作 a).spring创建对象 1.基于XML方式创建对象: <!-- 配置User对象的创建--><bean id = "us ...

  6. [Spring] 注入Bean属性

    通常,JavaBean的属性是私有的,同时拥有一组存取器方法,setXXX()和getXXX()形式存在.Spring可以借助属性的set方法来配置属性的值,以实现setter方式的注入. Kenny ...

  7. Spring注入属性为null

    问题描述 下面这个bean在创建对象后pageNum和pageSize都有值,但是在Spring注入后的值是null public class QuestionDTO implements Seria ...

  8. Spring 注入static属性值

    Spring 注入static属性值 本文介绍Spring中如何从属性文件给static字段注入值.实际应用中一些工具类中static属性值需读取配置文件,实现该功能可以让工具类提供静态方法更易使用. ...

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

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

最新文章

  1. 区分 JVM 内存结构、 Java 内存模型 以及 Java 对象模型 三个概念
  2. Linus Torvalds将中国亮相LinuxCon + ContainerCon + CloudOpen
  3. linux下升级python2.0到python3.0
  4. 如何在windows系统上安装Tensorflow Object Detection API?
  5. Android开发:《Gradle Recipes for Android》阅读笔记1.3
  6. 搬家后第一次缴电费,查询客户编号的解决办法
  7. NVelocity标签设置缓存的解决方案
  8. 入口函数ufusr()的示例 3.2.2
  9. 基于JAVA+Servlet+JSP+MYSQL的高校后勤管理系统
  10. jvm堆内存设置原理
  11. linux 运行库 编译参数,Linux/CentOS 升级C基本运行库CLIBC的注意事项(当想解决GLIBC_2.x找不到的编译问题)...
  12. jquery获取和设置属性_jQuery获取属性,设置属性,删除属性
  13. 利用Bat命令批量修改文件名
  14. SVN 小乌龟(TortoiseSVN)本地文件更新报错Another process is blocking the working copy database 解决方法
  15. 怎么开通PayPal支付?PayPal支付账号申请流程步骤
  16. 进行日常记账后,怎样导出表格
  17. ckeditor使用
  18. 解决视频文件播放不能快进问题
  19. 如何运行jnlp文件
  20. 承接WEB应用开发、软件开发、网站开发

热门文章

  1. 嵌入式开发之工具---比开发手册更重要的一个命令 man page
  2. 链表节点合并排序:数组和单链表
  3. FreeSwitch自带的电话会议
  4. Dreamweaver 8的后台文件传输
  5. 屏幕边框闪光_写给想入手21:9的屏幕党,明基 EX3501R 真香跳坑指南
  6. 牛客华为机试第7题python
  7. 数据集和神经网络共同进步之代码之路
  8. cookies池和proxy池
  9. HotSpot虚拟机对象的创建过程
  10. CentOS 7.3 安装MySQL--Java--Tomcat