`
zeng916cn
  • 浏览: 37538 次
  • 性别: 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的声明式事务管理也是个不错的选择。
分享到:
评论

相关推荐

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

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

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

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

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

    本代码使用H2内存数据库演示spring事务使用,包括编程式事务,声明式事务@Transactional使用,自定义事务事务注解实现自定义事务管理器

    Spring JDBC与事务管理

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

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

    Spring 的事务管理是 Spring 框架中一个比较重要的知识点,该知识点本身并不复杂,只是由于其比较灵活,导致初学者很难把握。本教程从基础知识开始,详细分析了 Spring 事务管理的使用方法,为读者理清思路。

    班级事务管理系统UML

    本压缩文件内包括了一份用EA编写的班级事务管理系统的文件和一份基于些文件编写的班级事务管理系统分析的文档

    企业日常事务管理系统

    企业日常事务管理系统 为企业内部通信提供最简便的服务!数据库mysql

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

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

    Spring事务管理Demo

    Spring事务管理Demo

    fastadmin事务管理系统

    fastadmin事务管理系统

    数据库期末项目(教学事务管理系统).zip

    本学期分组完成“教学事务管理系统”,具体要求如下: 1. 系统必须是在B/S结构下实现。 2. 数据库在原理1的School数据库基础下自行修改,只能添加,不能删除。 3. 系统具有为不同的角色(系统管理员、教师、学生)...

    鸿言事务管理软件v3.0免费安装版

    鸿言事务管理软件是一款个人事务管理软件,具有事务分类、事务提醒、处理记录和处理进度等功能,事务太多,左支右绌?鸿言事务管理可以帮您解决问题 鸿言事务管理软件官方介绍 鸿言事务管理是用来管理个人事务、...

    教学事务管理系统 java 源代码

    教学事务管理系统 java 源代码很经典的系统

    C#开发的事务管理系统,源代码

    C#开发的事务管理系统 1.日历界面 2.创建指定日期或时间段的事务 3.事务闹铃提醒 4.日记功能,阅读日记的密码保护功能 5.帐号管理,可以切换用户 6.源代码公开 7.ACCESS数据库,无需繁琐的安装步骤即可马上使用 8.C# ...

    班级事务管理系统3.

    班级事务管理是作为一个班级集体管理的一项主要任务,功能完善及安全可靠的管理系统可以大大提高学校资源的利用率,实时准确地了解班级成员与集体的现行状况,同时有助于学校管理。本系统是根据班级事务及各个过程...

    JavaEE的Spring JDBC与事务管理 实验

    3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握基于XML和Annotation的声明式事务管理的使用。 二、 实验内容 1、在MySQL中创建以下三张表,其中account为账户表,book为书籍信息...

    个人事务管理系统

    设计一个个人事务管理系统 public ResultSet executeSelect(String inquire) throws SQLException { //执行数据库查询操作 rs = stmt.executeQuery(inquire); return rs; } …… …… public boolean ...

    基于java的企业级应用开发:声明式事务管理.ppt

    使用@Transactional注解时,可以通过参数配置事务详情: 5.2.2 基于Annotation方式的声明式事务 * * * * * * * * 声明式事务管理 如何实现Spring的声明式事务管理? 5.2 声明式事务管理 Spring的声明式事务管理可以...

    论文研究 - 基于博客的高校辅导员学生事务管理平台项目

    随着高校规模的逐步扩大,学生事务管理问题如学生过多,辅导员数量不足等问题日益突出。 在这种新情况下,无疑是改变以前的管理模式,并为高校辅导员建立基于博客的学生事务管理平台项目的开创性尝试。 通过将...

    从零开始学iOS7开发系列教程-事务管理软件开发实战

    从零开始学iOS7开发系列教程-事务管理软件开发实战 包括pdf 和源码 一共9章

Global site tag (gtag.js) - Google Analytics