`
zeng916cn
  • 浏览: 38453 次
  • 性别: Icon_minigender_1
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论
阅读更多
10.8 事务管理
Hibernate建议所有的数据库访问都应放在事务内进行,即使只进行只读操作。事务又应该尽可能地短,长事务会导致系统长时间无法释放,因而降低系统并发的负载。Spring同时支持编程式事务和声明式事务。尽量考虑使用声明式事务,声明式事务管理可分离业务逻辑和事务管理逻辑,具备良好的适应性。
10.8.1 编程式的事务管理
编程式事务管理建议使用TransactionTemplate来完成事务操作,TransactionTemplate采用Callback避免让开发者重复书写打开事务,提交事务,回滚事务等代码,同时,TransactionTemplate无须书写大量的try...catch块。
关于使用TransactionTemplate的示例,请参阅7.4.1使用TransactionTemplate。需要是使用Spring的事务管理,首先需配置一个PlatformTransactionManager bean。配置该bean时,应根据事务环境选择合适的实现类。下面示例是Hibernate局部事务管理的配置示例:
<?xml version="1.0" encoding="gb2312"?>
<!--  Spring配置文件的DTD定义-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<!--  Spring配置文件的根元素是beans-->
<beans>
         <!--定义数据源,该bean的ID为dataSource-->
         <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                   <!--  指定数据库驱动-->
           <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
                   <!--  指定连接数据库的URL-->                 
           <property name="url"><value>jdbc:mysql://wonder:3306/j2ee</value></property>
                   <!--  root为数据库的用户名-->
           <property name="username"><value>root</value></property>
                   <!--  pass为数据库密码-->
           <property name="password"><value>pass</value></property>
    </bean>
         <!--定义Hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
           <!--  依赖注入数据源,注入正是上文定义的dataSource>
           <property name="dataSource"><ref local="dataSource"/></property>
                   <!--  mappingResouces属性用来列出全部映射文件>
           <property name="mappingResources">
                <list>
                     <!--以下用来列出所有的PO映射文件-->
                                     <value>lee/MyTest.hbm.xml</value>
                </list>
           </property>
          <!--定义Hibernate的SessionFactory的属性 -->
           <property name="hibernateProperties">
                    <props>
                                     <!--  指定Hibernate的连接方言-->
                                     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                                     <!--  不同数据库连接,启动时选择create,update,create-drop-->
                         <prop key="hibernate.hbm2ddl.auto">update</prop>
                    </props>
        </property>
</bean>
<!--  配置Hibernate的事务管理器 -->
<!--  使用HibernateTransactionManager类,该类是PlatformTransactionManager接口
 针对采用Hibernate持久化连接的特定实现。-->
<bean id="transactionManager"
     class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!--  HibernateTransactionManager  bean需要依赖注入一个SessionFactory bean的引用-->
       <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
下面是采用TransactionTemplate和HibernateTemplate的事务操作代码:
public class TransactionTest
{
    public static void main(String[] args)
    {
                   //因为并未在Web应用中测试,故需要手动创建Spring的上下文
           final ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
                   //获得Spring上下文的事务管理器
         PlatformTransactionManager  transactionManager=
                            (PlatformTransactionManager)ctx.getBean("transactionManager");
         final SessionFactory sessionFactory  = (SessionFactory)ctx.getBean("sessionFactory ");
                            (PlatformTransactionManager)ctx.getBean("transactionManager");
                   //以事务管理器实例为参数,创建TransactionTemplate对象
                   TransactionTemplate tt = new TransactionTemplate(transactionManager);
                   //设置TransactionTemplate的事务传播属性
                   transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                   //执行TransactionTemplate的execute方法,该方法需要TransactionCallback实例。
                   tt.execute(new TransactionCallbackWithoutResult()
                            //采用TransactionCallbackWithoutResult匿名内部类的形式执行
                            {
                                     protected void doInTransactionWithoutResult(TransactionStatus ts)
                                     {
                                               try
                                               {
                                                        以SessionFactory实例为参数创建HibernateTemplate
                                                HibernateTemplate hibernateTemplate  =
                                                                 new HibernateTemplate(this.sessionFactory);
                                                        Person p1 = new Person(“Jack”);
                                                        //保存第一个实例
                                                        hibernateTemplate.save(p1);
                                                        //让下面的数据库操抛出异常即可看出事务效果。前面的操作也不会生效
                                                        Person p2 = new Person(“Black”);
                                                        //保存第二个实例,可将Person的name属性设为标识属性,并引起主键重复的异
//常,可看出前一条记录也不会进数据库
                                                        hibernateTemplate.save(p2);
 
                                               }
                                               catch (Exception e)
                                               {
                                                        ts.setRollbackOnly();
                                               }
                                     }
                            });
         }
}
10.8.2声明式的事务管理
通常建议采用声明式事务管理。
交叉参考:
声明式事务的配置,请参考7.5节 声明式事务的介绍。
关于声明式事务管理的配置方式,通常有如下三种:
q      使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。此方式是最传统,配置文件最臃肿、难以阅读的方式。
q      采用bean继承的事务代理配置方式,比较简洁,但依然是增量式配置。
q      使用BeanNameAutoProxyCreator,根据bean name自动生成事务代理的方式。
建议采用第三种配置方式,详细的配置代码如下:
<?xml version="1.0" encoding="gb2312"?>
<!--  Spring配置文件的DTD定义-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<!--  Spring配置文件的根元素是beans-->
<beans>
         <!--定义数据源,该bean的ID为dataSource-->
         <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                   <!--  指定数据库驱动-->
           <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
                   <!--  指定连接数据库的URL-->                 
           <property name="url"><value>jdbc:mysql://wonder:3306/j2ee</value></property>
                   <!--  root为数据库的用户名-->
           <property name="username"><value>root</value></property>
                   <!--  pass为数据库密码-->
           <property name="password"><value>pass</value></property>
    </bean>
         <!--定义Hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
           <!--  依赖注入数据源,注入上面定义的dataSource>
           <property name="dataSource"><ref local="dataSource"/></property>
                   <!--  mappingResouces属性用来列出全部映射文件>
           <property name="mappingResources">
                <list>
                     <!--以下用来列出所有的PO映射文件-->
                                     <value>lee/Person.hbm.xml</value>
                </list>
           </property>
          <!--定义Hibernate的SessionFactory的属性 -->
           <property name="hibernateProperties">
                    <props>
                                     <!--  指定Hibernate的连接方言-->
                                     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                                     <!--  不同数据库连接,启动时选择create,update,create-drop-->
                         <prop key="hibernate.hbm2ddl.auto">update</prop>
                    </props>
           </property>
    </bean>
<!--  配置Hibernate的事务管理器 -->
<!--  使用HibernateTransactionManager类,该类是PlatformTransactionManager接口。
       针对采用Hibernate持久化连接的特定实现。-->
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!--  HibernateTransactionManager  bean需要依赖注入一个SessionFactory bean的引用-->
       <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!--  定义事务拦截器bean>
         <bean id="transactionInterceptor"
        class="org.springframework.transaction.interceptor.TransactionInterceptor">
                  <!--  事务拦截器bean需要依赖注入一个事务管理器>
         <property name="transactionManager" ref="transactionManager"/>
                   <property name="transactionAttributes">
                            <!--  下面定义事务传播属性-->
                            <props>
                                     <prop key="insert*">PROPAGATION_REQUIRED </prop>
                                     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                                     <prop key="*">PROPAGATION_REQUIRED</prop>
                            </props>
                   </property>
         </bean>
<!—定义一个BeanPostProcessor bean
Spring提供BeanPostProcessor的实现类BeanNameAutoProxyCreator-->
         <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
                   <!--  指定对满足哪些bean name的bean自动生成业务代理 -->
                   <property name="beanNames">
                            <!--  此处还可以列出更多的需要生成事务代理的目标bean-->
                            <ref local=" personDAO "/>
                            <!--  有一个需要生成事务代理的目标bean, 此处就增加一行-->
                   </property>
                   <!--  下面定义BeanNameAutoProxyCreator所需要的事务拦截器-->
                   <property name="interceptorNames">
                            <list>
                                     <value>transactionInterceptor</value>
                  <!-- 此处还增加其他新的Interceptor -->
                            </list>
                   </property>
         </bean>
<bean id="personDAO" class="lee.PersonDAOImpl" />
<!—此处还可增加更多bean定义-->               
</beans>
TranscationInterceptor是一个事务拦截器bean,需要传入一个TransactionManager的引用。配置中使用Spring依赖注入该属性,事务拦截器的事务属性通过transactionAttributes来指定,该属性有props子元素,配置文件中定义了三个事务传播规则:
所有以insert开始的方法,采用PROPAGATION_REQUIRED的事务传播规则。程序抛出MyException异常及其子异常时,自动回滚事务。所有以find开头的方法,采用PROPAGATION_REQUIRED事务传播规则,并且只读。其他方法,则采用PROPAGATION_REQUIRED的事务传播规则。
BeanNameAutoProxyCreator是个根据bean名生成自动代理的代理创建器,该bean通常需要接受两个参数。第一个是beanNames属性,该属性用来设置哪些bean需要自动生成代理。另一个属性是interceptorNames,该属性则指定事务拦截器,自动创建事务代理时,系统会根据这些事务拦截器的属性来生成对应的事务代理。
10.8.3 事务策略的思考
考虑采用Spring的事务管理机制。Spring的事务管理都是通过PlatformTransactionManager完成。在Hibernate应用中,PlatformTransactionManager可能是Hibernat SessionFactory,也可能是 JtaTransactionManager。前者是采用局部事务管理的实现,后者是采用基于JTA支持的全局事务管理的实现。因此,即使应用运行于支持JTA事务的应用服务器环境,考虑使用Spring的声明式事务管理也是个不错的选择。
分享到:
评论

相关推荐

    spring 自定义事务管理器,编程式事务,声明式事务@Transactional使用

    在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本教程将深入探讨如何在Spring中实现自定义事务管理器、编程式事务处理以及声明式事务`@Transactional`的使用。 首先,让我们了解事务...

    Spring事务管理Demo

    在Spring框架中,事务管理是核心特性之一,它允许开发者以声明式或编程式的方式处理应用中的事务。Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何...

    fastadmin事务管理系统

    FastAdmin事务管理系统 FastAdmin事务管理系统是一种基于Web的事务管理系统,旨在帮助管理员更好地管理事务流程和数据。下面是该系统的一些重要知识点: 登录 Token 设计 FastAdmin的事务管理系统使用 Token-...

    班级事务管理系统UML

    【班级事务管理系统UML】是针对学校班级日常事务管理而设计的一种软件系统,它通过统一建模语言(Unified Modeling Language,简称UML)进行模型化描述和设计。UML是一种标准化的图形建模语言,广泛应用于软件工程...

    个人日常事务管理系统(java版)

    《个人日常事务管理系统(Java版)详解》 个人日常事务管理系统是现代生活中不可或缺的一部分,它帮助我们有效地组织和管理日常的琐碎事务,确保生活、工作有序进行。本系统采用Java编程语言开发,具备高度的安全性...

    Java Web项目企业事务管理系统源码

    Java Web项目企业事务管理系统源码,详细的代码注释 本系统的开发工具具体如下。 ● 系统开发平台:MyEclipse 6.5。 ● 数据库管理系统软件:MySQL 5.0。 ● 运行平台:Windows 2000/Windows XP/Windows 2003/...

    SSM中事务管理所需的jar包-aspectjweaver

    本文将详细讲解SSM框架中事务管理的概念、AspectJ的作用以及`aspectjweaver.jar`在事务管理中的应用。 1. **事务管理**:事务是数据库操作的基本单元,它确保一组操作要么全部成功,要么全部回滚,遵循ACID(原子性...

    全面分析_Spring_的编程式事务管理及声明式事务管理

    Spring 框架的事务管理是其核心特性之一,它为开发者提供了强大的支持,确保了在多线程和并发环境中数据的一致性和完整性。本教程将深入探讨 Spring 的编程式事务管理和声明式事务管理,帮助你理解这两种方式的差异...

    Spring事务管理开发必备jar包

    在Spring框架中,事务管理是实现业务逻辑时不可或缺的一部分,它确保了数据的一致性和完整性。本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理...

    毕业设计—基于Java的Acme班级事务管理系统.zip

    毕业设计—基于Java的Acme班级事务管理系统,已获老师指导并通过的高分项目。 毕业设计—基于Java的Acme班级事务管理系统,已获老师指导并通过的高分项目。毕业设计—基于Java的Acme班级事务管理系统,已获老师指导...

    全面分析 Spring 的编程式事务管理及声明式事务管理

    本文将全面分析Spring中的编程式事务管理和声明式事务管理,旨在帮助开发者深入理解这两种事务管理方式,并在实际项目中合理选择。 **编程式事务管理** 编程式事务管理是通过代码直接控制事务的开始、提交、回滚等...

    Xml文件配置实现声明式事务管理

    在Spring框架中,声明式事务管理是一种非常重要的特性,它允许开发者通过XML配置或注解来定义事务的边界,而无需在业务代码中显式地管理事务。这种方式极大地提高了代码的可读性和可维护性。本篇文章将深入探讨如何...

    Spring.NET学习笔记16——事务管理Demo源码

    Spring.NET是.NET平台上的一个轻量级开源框架,它借鉴了Java界的Spring框架,并提供了诸如依赖注入、面向切面编程以及事务管理等核心功能。在本篇“Spring.NET学习笔记16——事务管理Demo源码”中,我们将深入探讨...

    事务管理(C#)

    在IT领域,尤其是在数据库编程中,事务管理是一个至关重要的概念。C#作为一种广泛使用的编程语言,提供了丰富的功能来处理事务,确保数据的一致性和完整性。本文将深入探讨C#中的事务管理,包括基本概念、使用场景、...

    Spring JDBC与事务管理

    javaEE 实验三 Spring JDBC与事务管理, 一、实验目的 1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用; 3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握...

    Visual C++源代码 112 如何使用事务管理删除数据库记录

    Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库...

    spring hibernate 事务管理学习笔记(二)

    在本篇“Spring Hibernate 事务管理学习笔记(二)”中,我们将深入探讨Spring框架与Hibernate集成时如何实现高效、安全的事务管理。这是一篇关于源码分析和技术工具使用的文章,适合对Java开发和数据库操作有基础...

    事务管理(二)——SQL SERVER的事务管理

    在SQL Server中,事务管理是数据库操作的核心组成部分,它确保数据的一致性和完整性。这篇博客“事务管理(二)——SQL SERVER的事务管理”可能详细介绍了SQL Server如何处理事务,包括事务的特性、隔离级别以及如何...

Global site tag (gtag.js) - Google Analytics