由openSession、getCurrentSession和HibernateDaoSupport浅谈Spring对事物的支持

由openSession、getCurrentSession和HibernateDaoSupport浅谈Spring对事物的支持

    Spring和Hibernate的集成的一个要点就是对事务的支持,openSession、getCurrentSession都是编程式事务(手动设置事务的提交、回滚)中重要的对象,HibernateDaoSupport则提供了更方便的声明式事务支持。

    Hibernate中最重要的就是Session对象的引入,它是对jdbc的深度封装,包括对事务的处理,Session对象通过SessionFactory来管理,openSession和getCurrentSession是管理session的重要的方法。

    openSession和getCurrentSession的根本区别在于有没有绑定当前线程,所以,使用方法有差异:

* openSession没有绑定当前线程,所以,使用完后必须关闭,

* currentSession和当前线程绑定,在事务结束后会自动关闭。

关于事务的边界和传播:

     通常情况下事务的边界需要设置在业务逻辑处理层中,但是,如果在一个业务中涉及到多个业务逻辑层之间的方法,且需要在同一个事务中运行,那么,这就涉及到了事务的传播性。

如果使用openSession,就要在dao层的方法中传递session,而这种做法是很糟糕的,首先增加了参数的个数,另外,方法是否需要事务,完全是可以当做一种独立的服务抽离出的。

因为currentSession是线程级别的,所以,只要业务逻辑方法在同一个线程中,就不会担心上面的问题。这也是currentSession的一个优越处之一。

使用currentSession:

1.在配置文件中将线程配置成Thread级别的。

 

[html] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px"><propertynamepropertyname="hibernate.current_session_context_class">thread</property></SPAN>  
<propertyname="hibernate.current_session_context_class">thread</property>

2.调用sessionFactory的getCurrentSession方法:

 

[java] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">publicvoid addUser(User user) {  
  2.   
  3.     Session session = null;  
  4.   
  5.     try {  
  6.   
  7.        session =HibernateUtils.getSessionFactory().getCurrentSession();  
  8.   
  9.        session.beginTransaction();        
  10.   
  11.        session.save(user);          
  12.   
  13.        Loglog = new Log();  
  14.   
  15.        log.setType("操作日志");  
  16.   
  17.        log.setTime(new Date());  
  18.   
  19.        log.setDetail("XXX");        
  20.   
  21.        LogManager logManager = newLogManagerImpl();  
  22.   
  23.        logManager.addLog(log);         
  24.   
  25.        session.getTransaction().commit();  
  26.   
  27.     }catch(Exception e) {  
  28.   
  29.        e.printStackTrace();  
  30.   
  31.        session.getTransaction().rollback();     
  32.   
  33.     }  
  34.   
  35. }</SPAN>  
publicvoid addUser(User user) {Session session = null;try {session =HibernateUtils.getSessionFactory().getCurrentSession();session.beginTransaction();      session.save(user);        Loglog = new Log();log.setType("操作日志");log.setTime(new Date());log.setDetail("XXX");      LogManager logManager = newLogManagerImpl();logManager.addLog(log);       session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();   }}

 

使用openSession:

 

[java] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">public void addUser(User user) {  
  2.   
  3.       Sessionsession = null;  
  4.   
  5.       try{  
  6.   
  7.          session= HibernateUtils.getSession();  
  8.   
  9.          session.beginTransaction();  
  10.   
  11. // 若干操作…………           
  12.   
  13.          session.getTransaction().commit();  
  14.   
  15.       }catch(Exceptione) {  
  16.   
  17.          e.printStackTrace();  
  18.   
  19.          session.getTransaction().rollback();  
  20.   
  21.       }finally{  
  22.   
  23.          HibernateUtils.closeSession(session);  
  24.   
  25.       }  
  26.   
  27.    }  
  28.   
  29.  </SPAN>  
public void addUser(User user) {Sessionsession = null;try{session= HibernateUtils.getSession();session.beginTransaction();// 若干操作…………        session.getTransaction().commit();}catch(Exceptione) {e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}

使用HibernateDaoSupport声明式事务:

    Spring与Hibernate的集成使用最多的是HibernateDaoSupport,它对session的获取以及事务做了进一步的封装,只需要关注dao的实现,而不用担心某个地方的事务是否关闭。

 

[java] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">this.getHibernateTemplate().save(user);</SPAN>  
this.getHibernateTemplate().save(user);

 

关于异常与事务回滚:   

    Spring在遇到运行期异常(继承了RuntimeException)的时候才会回滚,如果是Exception(如用户输入密码错误)抛出就好,事务会继续往下进行。

    Spring对异常的处理的灵活性还是比较高的,可以配置遇到某个Exception进行回滚,某个RuntimeException不回滚,但是对于EJB就没有这么灵活了,EJB相当于是固定的套餐。

不会回滚:  

 

[java] view plaincopyprint?
  1. public void addUser(User user)  
  2.   
  3.    throws Exception {  
  4.   
  5.       this.getHibernateTemplate().save(user);  
  6.   
  7.          //若干操作……             
  8.   
  9.       throw new Exception();  
  10.   
  11.    }  
public void addUser(User user)throws Exception {this.getHibernateTemplate().save(user);//若干操作……          throw new Exception();}
 

回滚:

 

[java] view plaincopyprint?
  1. public void addUser(User user) {  
  2.   
  3.        this.getHibernateTemplate().save(user);      
  4.   
  5.        //若干操作……          
  6.   
  7.        throw new RuntimeException();  
  8.   
  9.  }  
  public void addUser(User user) {this.getHibernateTemplate().save(user);    //若干操作……       throw new RuntimeException();}

 

 

Spring与Hibernate的集成,使用HibernateDaoSupport的配置:

   在ssh框架应用中,Spring与Hibernate的事务集成基本上是比较固定的,我们把事务的集成单独配置到applicationContext-common.xml中:

 

[html] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px"><?xml version="1.0"encoding="UTF-8"?>   
  2.   
  3. <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"  
  4.   
  5.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.   
  7.        xmlns:aop="http://www.springframework.org/schema/aop"  
  8.   
  9.        xmlns:tx="http://www.springframework.org/schema/tx"  
  10.   
  11.         xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  12.   
  13.           http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  14.   
  15.            http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
  16.   
  17.    <!--配置SessionFactory -->  
  18.   
  19.    <beanidbeanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  20.   
  21.       <propertynamepropertyname="configLocation">  
  22.   
  23.          <value>classpath:hibernate.cfg.xml</value>  
  24.   
  25.       </property>  
  26.   
  27.    </bean>  
  28.     
  29.   
  30.    <!--配置事务管理器 -->  
  31.   
  32.    <beanidbeanid="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  33.   
  34.       <propertynamepropertyname="sessionFactory">  
  35.   
  36.          <refbeanrefbean="sessionFactory"/>          
  37.   
  38.       </property>  
  39.   
  40.    </bean>  
  41.     
  42.   
  43.    <!--那些类那些方法使用事务 -->  
  44.   
  45.    <aop:config>  
  46.   
  47.       <aop:pointcutidaop:pointcutid="allManagerMethod" expression="execution(*com.bjpowernode.usermgr.manager.*.*(..))"/>  
  48.   
  49.       <aop:advisorpointcut-refaop:advisorpointcut-ref="allManagerMethod" advice-ref="txAdvice"/>  
  50.   
  51.    </aop:config>  
  52.     
  53.   
  54.    <!--事务的传播特性 -->   
  55.   
  56.    <tx:adviceidtx:adviceid="txAdvice" transaction-manager="transactionManager">  
  57.   
  58.       <tx:attributes>  
  59.   
  60.          <tx:methodnametx:methodname="add*" propagation="REQUIRED"/>  
  61.   
  62.          <tx:methodnametx:methodname="del*" propagation="REQUIRED"/>  
  63.   
  64.          <tx:methodnametx:methodname="modify*" propagation="REQUIRED"/>  
  65.   
  66.          <tx:methodnametx:methodname="*" propagation="REQUIRED"read-only="true"/>  
  67.   
  68.       </tx:attributes>  
  69.   
  70.    </tx:advice>  
  71.   
  72. </beans></SPAN>  
<?xml version="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!--配置SessionFactory --><beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><propertyname="configLocation"><value>classpath:hibernate.cfg.xml</value></property></bean><!--配置事务管理器 --><beanid="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><propertyname="sessionFactory"><refbean="sessionFactory"/>        </property></bean><!--那些类那些方法使用事务 --><aop:config><aop:pointcutid="allManagerMethod" expression="execution(*com.bjpowernode.usermgr.manager.*.*(..))"/><aop:advisorpointcut-ref="allManagerMethod" advice-ref="txAdvice"/></aop:config><!--事务的传播特性 --> <tx:adviceid="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:methodname="add*" propagation="REQUIRED"/><tx:methodname="del*" propagation="REQUIRED"/><tx:methodname="modify*" propagation="REQUIRED"/><tx:methodname="*" propagation="REQUIRED"read-only="true"/></tx:attributes></tx:advice></beans>
 

 

因为在hibernate.cfg.xml中添加了如下配置,所以,在tomcat等容器启动的时候,会自动将相应的bean对象创建。

 

[html] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px"<propertynamepropertyname="hibernate.hbm2ddl.auto">update</property></SPAN>  
    <propertyname="hibernate.hbm2ddl.auto">update</property>

 

applicationContext-beans.xml:

    通常将业务逻辑对实现类的引用单独的xml文件中,同时,在实现类中不能忽略sessionFactory工厂的注入。

 

[html] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px"><?xml version="1.0"encoding="UTF-8"?>   
  2.   
  3. <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"  
  4.   
  5.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.   
  7.         xmlns:aop="http://www.springframework.org/schema/aop"  
  8.   
  9.        xmlns:tx="http://www.springframework.org/schema/tx"  
  10.   
  11.        xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  12.   
  13.            http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  14.   
  15.           http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
  16.   
  17.             
  18.   
  19.    <beanidbeanid="userManager" class="com.bjpowernode.usermgr.manager.UserManagerImpl">  
  20.   
  21.       <propertynamepropertyname="sessionFactory" ref="sessionFactory"/>  
  22.   
  23.       <propertynamepropertyname="logManager" ref="logManager"/>  
  24.   
  25.    </bean>  
  26.     
  27.   
  28.    <beanidbeanid="logManager"class="com.bjpowernode.usermgr.manager.LogManagerImpl">  
  29.   
  30.       <propertynamepropertyname="sessionFactory" ref="sessionFactory"/>  
  31.   
  32.    </bean>  
  33.   
  34. </beans></SPAN>  
<?xml version="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><beanid="userManager" class="com.bjpowernode.usermgr.manager.UserManagerImpl"><propertyname="sessionFactory" ref="sessionFactory"/><propertyname="logManager" ref="logManager"/></bean><beanid="logManager"class="com.bjpowernode.usermgr.manager.LogManagerImpl"><propertyname="sessionFactory" ref="sessionFactory"/></bean></beans>

事务传播特性:

   为了保证调用的业务逻辑方法都使用同一个事务,通常都使用REQUIRED这个级别,它表示:如果上一个方法中有事务,就直接使用,如果没有,就创建一个事务,这样,一旦事务创建了后,后续调用的方法就不会再创建。

   其他的事务传播特性见下表:


 

Spring事务的隔离级别:

   1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。

        另外四个与JDBC的隔离级别相对应。

   2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。

        这种隔离级别会产生脏读,不可重复读和幻像读。

   3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

   4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

        它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

   5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

     除了防止脏读,不可重复读外,还避免了幻像读。

    事务隔离级别主要应用在对大数据的处理方面,与锁的机制是密不可分的,这里不赘述。

转载于:https://www.cnblogs.com/gtaxmjld/p/4819725.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go返回多个值和python返回多个值对比

go package mulVals_test import "testing" func returnMultiValues(n int)(int, int){return n1, n2 }func TestReturnMultiValues(t *testing.T) {// a : returnMultiValues(5)// 这里尝试用一个值接受多个返回值&#xff0c;将编译错误a, _ : returnMultiValues(…

努力学习 HTML5 (3)—— 改造传统的 HTML 页面

要了解和熟悉 HTML5 中的新的语义元素&#xff0c;最好的方式就是拿一经典的 HTML 文档作例子&#xff0c;然后把 HTML5 的一些新鲜营养充实进入。如下就是我们要改造的页面&#xff0c;该页面很简单&#xff0c;只包含一篇文章。 ApocalypsePage_Original.html&#xff0c;这是…

判断系统是大端还是小段

大端&#xff1a;高位内存存储低序字节小端&#xff1a;高位内存存储高序字节short a 0x0102&#xff0c;其中 01 高序字节&#xff0c; 02 低序字节 #include<stdio.h>int main() {union {short s;char c[sizeof(short)];} un;un.s 0x0102;if (sizeof(short) 2) {if…

C语言判断系统是32位还是64位

long 在 32 位系统中是 4 字节&#xff0c;与 int 表示范围相同&#xff0c;在 64 位系统中是 8 字节。 #include <stdio.h> #include <stdlib.h> #include <limits.h>int main() {long a INT_MAX;if (a 1 < 0) {printf("32: %ld\n", a);} e…

使用Eclipse搭建Struts2框架

本文转自http://blog.csdn.net/liaisuo/article/details/9064527 今天在Eclipse搭建了Struts2 框架&#xff0c;并完成了一个很简单的例子程序。 搭建好的全局图如下: 第一步:在http://struts.apache.org/download.cgi下载Struts2的最新版即下载Full Distribution&#xff0c;这…

autoLayout自动布局

autoLayout 有两个核心概念&#xff1a; 约束&#xff1a;就是对控件进行高度&#xff0c;宽度&#xff0c;相对位置的控制 参照&#xff1a;多个控件时&#xff0c;一个或多个控件以其中的一个为基准进行高度&#xff0c;宽度&#xff0c;位置的设置 当选择了 use auto layout…

JDBC连接(MySql)数据库步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能。...

主要内容&#xff1a; JDBC连接数据库步骤。一个简单详细的查询数据的例子。封装连接数据库&#xff0c;释放数据库连接方法。实现查询&#xff0c;插入&#xff0c;删除&#xff0c;更新等十一个处理数据库信息的功能。&#xff08;包括事务处理&#xff0c;批量更新等&#x…

C++学习笔记25,析构函数总是会宣布virtual

为了永远记住析构函数声明virtual----><<effective c>> 为这句话不一定对,但无需质疑的是这句话是非常实用的. 查看以下的样例: #include <iostream> #include <string> using namespace std; class B{ public:~B(){cout<<"base is dest…

各大互联网公司2014前端笔试面试题–JavaScript篇

很多面试题是我自己面试BAT亲身经历碰到的。整理分享出来希望更多的前端er共同进步吧&#xff0c;不仅适用于求职者&#xff0c;对于巩固复习js更是大有裨益。 而更多的题目是我一路以来收集的&#xff0c;也有往年的&#xff0c;答案不确保一定正确&#xff0c;如有错误或有更…

iOS:苹果企业证书通过网页分发安装app

本文转载至 http://blog.sina.com.cn/s/blog_6afb7d800101fa16.html 苹果的企业级证书发布的应用&#xff0c;是不用设备授权即可直接安装&#xff0c;并且不限设备上限。为了方便分发&#xff0c;苹果有协议实现通过网页链接直接下载安装企业级的应用。 基本的原理就是在生成企…

这道题很难

请编写一个函数&#xff0c;使其可以删除某个链表中给定的&#xff08;非末尾&#xff09;节点。传入函数的唯一参数为 要被删除的节点 。 现有一个链表 – head [4,5,1,9]&#xff0c;它可以表示为: 示例 1&#xff1a; 输入&#xff1a;head [4,5,1,9], node 5 输出&a…

设计模式学习笔记-基础知识篇

1. 设计模式的重要性 1.1 设计模式解决的是在软件过程中如何来实现具体的软件功能。实现同一个功能的方法有很多&#xff0c;哪个设计容易扩展&#xff0c;容易复用&#xff0c;松耦合&#xff0c;可维护&#xff1f;设计模式指导我们找到最优方案。 1.2 设计中往往会存在设计缺…

内心的平静就是财富本身-Cell组件-用友华表的由来-T君

时至今日&#xff0c;Cell组件仍是应用广泛的商业报表组件 作者&#xff1a;人生三毒 编者注&#xff1a;本文作者人生三毒为知名网站及网页游戏公司创始人&#xff0c;此前曾为IT类媒体资深编辑&#xff0c;见证了中国互联网早期的发展。 认识T君之前先认识的是他的软件&#…

C++实现一个http服务器

一个简单的博客后端服务器 github地址&#xff0c;持续更新 设计参考 #define MYSQLPP_MYSQL_HEADERS_BURIED #include "httplib.h" #include "rapidjson/document.h" #include <mysql/mysql.h> #include <iostream> #include <string>…

KMP算法的java实现

package com.trs.utils;public class KMPStr {/** 在KMP算法中&#xff0c;最难求的就是next函数&#xff0c;如何理解next函数是一个难题&#xff0c;特别是knext[k]&#xff0c;这里* 需要指出的是当p[i]!p[j]时&#xff0c;我们只有通过回溯将k的值逐渐减小&#xff0c;貌似…

线段分割法实现微信抢红包

无意间看到的一种实现抢红包的方法&#xff0c;于是用C实现了一下。 将一个红包分成 n 份 具体的思路是&#xff0c;将一个红包看作是一个线段&#xff0c;线段的长就是红包总金额&#xff0c;然后在这个线段上随机切 n-1 刀&#xff0c;分成 n 份&#xff0c;然后抢红包的人依…

C++雪花算法实现

看来一下雪花算法的实现方法&#xff0c;用 c试着实现了一下&#xff0c;这里仅仅是实现了算法的流程&#xff0c;但是具体的细节&#xff0c;如并发、多线程访问等等没有具体考虑。 雪花算法的简单讲解参考 #include <sys/select.h> #include <iostream> #includ…

CAlayer层的属性

iOS开发UI篇—CAlayer层的属性 一、position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性&#xff1a;position和anchorPoint property CGPoint position; 用来设置CALayer在父层中的位置 以父层的左上角为原点(0, 0) property CGPoint anchorPoint; 称为“定位点”、…

Odoo9发行说明

2015年10月1日&#xff0c;期待已久的Odoo9正式发布。本文是Odoo9正式版发行说明&#xff0c;基于官网资料翻译。 译者: 苏州-微尘原文地址&#xff1a;https://www.odoo.com/page/odoo-9-release-notes译文地址&#xff1a;http://blog.csdn.net/wangnan537/article/details/4…

揭秘史上最完美一步到位的搭建Andoriod开发环境

Windows环境下Android开发环境搭建虽然不难而且网上资料众多&#xff0c;但是众多资料如出一折 忽略了很多细节&#xff0c;最终还是没能达到满意效果。 基本步骤如下&#xff1a;JDK安装、环境变量配置、Eclipse下载、AndoriodSDK下载安装、下载配置ADT但是到这里还不算完美搞…