ssh 事务

、 准备工作:

可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的 HibernateDaoSupport,则可以更轻松的实现

关键就在于配置文件,下面看一个样例app.xml:

<?xml version="1.0" encoding="utf-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">

<!--配置数据源-->

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

  <!-- 指定连接数据库的驱动 -->

  <property name="driverClass" value="com.mysql.jdbc.Driver"/>

  <!-- 指定连接数据库的URL -->

  <property name="jdbcUrl" value="jdbc:mysql://localhost/auction"/>

  <!-- 指定连接数据库的用户名 -->

  <property name="user" value="root"/>

  <!-- 指定连接数据库的密码 -->

  <property name="password" value="root"/>

  <!-- 指定连接数据库连接池的最大连接数 -->

  <property name="maxPoolSize" value="20"/>

  <!-- 指定连接数据库连接池的最小连接数 -->

  <property name="minPoolSize" value="1"/>

  <!-- 指定连接数据库连接池的初始化连接数 -->

  <property name="initialPoolSize" value="1"/>

  <!-- 指定连接数据库连接池的连接的最大空闲时间 -->

  <property name="maxIdleTime" value="20"/>

</bean>

 

<!--配置数据库会话工厂-->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

  <property name="dataSource" ref="dataSource"/>

  <property name="mappingResources">

    <list>

    <value>com/ouya/User.hbm.xml</value>

    </list>

  </property>

  <property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>

</props>

</property>

</bean>

 

<!-- 配置事务管理器-->

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory"><ref local="sessionFactory"/></property>

</bean>

<!—-配置Spring 事务管理器代理 -->

<bean id="transactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager">

    <ref local="transactionManager"/>

</property>

<property name="transactionAttributes">

    <props>

    <prop key="save*">PROPAGATION_REQUIRED</prop>

    <prop key="insert*">PROPAGATION_REQUIRED</prop>

    <prop key="del*">PROPAGATION_REQUIRED</prop>

    <prop key="add*">PROPAGATION_REQUIRED</prop>

    <prop key="update*">PROPAGATION_REQUIRED</prop>

    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

<!-- Hibernate模板 -->

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory">

<ref local="sessionFactory" />

</property>

</bean>

<!--服务层对象-->

<bean id="us" class="com.ouya.UserService">

<property name="userDao">

  <ref local="userDao"/>

</property>

</bean>

<!-- spring代理用户服务对象 -->

<bean id="userService" parent="transactionProxyFactory">

<!-- 如果上面的服务层对象实现了接口,则此处必须设置proxyTargetClass为true,否则会报classcast异常 -->

<!--<property name="proxyTargetClass" value="true"/>-->

  <property name="target" ref="us"/>

</bean>

<!-- 用户数据访问对象DATA ACCESS OBJECT -->

<bean id="userDao" class="com.ouya.UserDAO">

<property name="hibernateTemplate" ref="hibernateTemplate"/>

</bean>

</beans>

可以看到配置文件的步骤:

1、 配置数据源

2、 配置会话工厂(依赖注入上面的数据源,还要注入hbm映射文件[注意正确的位置]、hibernate属性文件)

3、 配置事务管理器(依赖注入上面的会话工厂)

4、 Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes)

后面的一些普通的bean配置就不用说了

上面的例子中使用的声明事务管理器是:TransactionProxyFactoryBean,这样的话我们就需要在后面配置目标bean,比如上面的例子中我们的原服务对象是id为 us的UserService(没有实现接口),所以我们为他配置了id为userService的代理对象(目标bean),程序中使用时只能通过使用代理对象才能实现数据库操作功能(代理对象的父类是上面声明的事务管理器,一边我们使用的时候开启事务),如果直接使用服务对象就无法开启事务

程序中调用:UserService us = (UserService) app.getBean("userService");

注:userService 就是上面配置的代理对象的id,而不是原服务对象的id

 

但是如果我们想通过原服务对象的id来使用对象,则我们需要使用代理事务管理器BeanNameAutoProxyCreator(根据beanname自动代理),上面的配置文件需要做改动,做两件事(当然先要删除原来配置的TransactionProxyFactoryBean,不然就混乱了,可能会报错的):

1、 增加一个事务拦截器

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">

<property name="transactionManager">

    <ref local="transactionManager"/>

</property>

<property name="transactionAttributes">

    <props>

    <prop key="save*">PROPAGATION_REQUIRED</prop>

    <prop key="insert*">PROPAGATION_REQUIRED</prop>

    <prop key="del*">PROPAGATION_REQUIRED</prop>

    <prop key="add*">PROPAGATION_REQUIRED</prop>

    <prop key="update*">PROPAGATION_REQUIRED</prop>

    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>

    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

2、 定义自动代理事务管理器

<!-- 定义BeanNameAutoProxyCreator-->

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<!-- 如果服务层对象是接口实现类,则需要设置proxyTargetClass属性为true -->

<!--<property name="proxyTargetClass" value="true"-->

  <!-- 指定对满足哪些bean name的bean自动生成业务代理 -->

  <property name="beanNames">

    <!-- 下面是所有需要自动创建事务代理的bean-->

    <list>

      <value>us</value>

    </list>

    <!-- 此处可增加其他需要自动创建事务代理的bean-->

  </property>

  <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->

  <property name="interceptorNames">

    <list>

      <!-- 此处可增加其他新的Interceptor -->

      <value>transactionInterceptor</value>

    </list>

  </property>

</bean>

然后我们在程序中调用时应如下:

UserService us = (UserService) app.getBean("us");

注:注意与上面使用TransactionProxyFactoryBean时的调用区别,此处我们用getbean时直接取原服务层对象的id,不需要去配置目标bea,这也正是

BeanNameAutoProxyCreator(根据bean名称自动代理)的含义所在

 

附录:

1、关于hibernate的属性详解:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

<!-- 以下配置都是使用 jdbc.properties 属性文件中的配置,而之所以可以这样写,就是因为有 属性占位符配置的原因 -->

<property name="driverClass" value="${jdbc.driverClassName}"/>

<property name="jdbcUrl" value="${jdbc.url}"/>

<property name="user" value="${jdbc.username}"/>

<property name="password" value="${jdbc.password}"/>

<!-- 连接池维持的最小的连接个数 -->

<property name="minPoolSize" value="5"/>

<!-- 连接池维持的最大的连接个数 -->

<property name="maxPoolSize" value="20"/>

<!-- 最大空闲时间, 当某个连接在这个时间内没活动后将从池中移除,前提是池中至少多于最少的连接数: minPoolSize -->

<property name="maxIdleTime" value="1800"/>

<!-- 为加强准备语句的执行性能,此参数指定被缓存的 PreparedStatement 的个数 -->

<property name="maxStatements" value="50"/>

</bean>

 

Hibernate 会话厂 SessionFactory

Session 就是用于每次与数据库会话的,因此需要:

数据库的配置参数,这些参数就是 上面的数据源指定的! 因此我们只需引用即可: ref="dataSource";

实体映射配置 hibernate.cfg.xml 配置

结果缓存配置(这里使用的是开源的 ehcache)

 

<!-- Hibernate SessionFactory -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<!-- 引用前面定义的数据源 -->

<property name="dataSource" ref="dataSource"/>

<!-- 所有实体映射文件列表, 所有的 hbm.xml 文件 -->

<property name="mappingResources">

<list>

<value>org/springframework/samples/jpetstore/domain/Account.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Banner.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Category.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Inventory.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Item.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/LineItem.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Order.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Product.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Supplier.hbm.xml</value>

</list>

</property>

<!-- 传统上的 hibernate.cfg.xml 文件的参数放在这里 -->

<property name="hibernateProperties">

<props>

<!-- 指定数据库方言 -->

<prop key="hibernate.dialect">${hibernate.dialect}

</prop>

<!-- 是否在日志中输出所有Hibernate与数据库交互的SQL语句 -->

<prop key="hibernate.show_sql">true</prop>

<!-- 是否在日志中输出的SQL 语句格式化成易读形式 -->

<prop key="hibernate.format_sql">true</prop>

<!-- 是否显示统计形式,一般在测试阶段使用 -->

<prop key="hibernate.generate_statistics">true</prop>

<!-- 对于级联查询,一次性获取的级联深度, @todo 需进一步研究 -->

<prop key="hibernate.max_fetch_depth">2</prop>

<!--

Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。

Oracle 数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,

超出100,性能提升不明显,反而会消耗内存。

-->

<prop key="hibernate.jdbc.fatch_size">100</prop>

<!--

不必等到累计到50个SQL之后才执行.只要事务commit后,不管缓存中有多少条sql语句都要执行.

hibernate.jdbc.batch_size 参数只是设定一次最多可以提交多少sql语句的上限,提高sql语句的执行效率

-->

<prop key="hibernate.jdbc.batch_size">50</prop>

<!--

(1)create 在每次SesstionFactory 构建时(一般是应用重启时,或者伴随着应用服务器重启时),先将之前数据库中的所有数据全

部清空,后紧跟着根据所有的hbm.xml 映射文件重新创建新的数据库表

 

(2)create-drop 除了create 的所有含义之外,在每次应用的退出前,将进行一次数据空清空。因此这个配置将有两次清空操作,

一次是退出,一次是启动时。

 

(3)update

如果在开发阶段理发了实体对象的映射文件(hbm.xml) 的定义后,此配置将后台的数据库表进行更新(如增加表的列)

 

(4)validate

用于校验现有的表与现有的配置是否一致。

-->

<prop key="hibernate.hbm2ddl.auto">update</prop>

<!-- 见下面的解释 -->

<prop key="hibernate.hbm2ddl.auto">update</prop>

<!--结果缓存配置:- 将ehcache.xml 置于 classpath 中- 如果不设置“查询缓存”,

那么hibernate只会缓存使用 load()方法获得的单个持久化对象,如果想缓存使用findall()、 list()、

Iterator()、 createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置

hibernate.cache.use_query_cache true 才行- 在Hbm文件中添加<cache usage="read-only"/>-

如果需要“查询缓存”,还需要在使用Query或Criteria()时设置其setCacheable(true);属性-->

<prop key="hibernate.cache.use_query_cache">true</prop>

<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

</props>

</property>

<!-- 为解决 merge()方法语义的歧义 @todo 以后进一步解析或者你可以看一下相应的文档 -->

<property name="eventListeners">

<map><entry key="merge">

<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>

</entry></map>

</property>

</bean>

 

2、Spring的transactionAttributes

 

PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

 

 

 

在SSH中常常用spring来管理hibernate的事务,我用到的配置如下:
第一种配置:首先配置全局文件,用来配置sessionFactory及事务管理器:
<!-- 定义hibernate的sessionFactory -->
<bean id="sessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation"
        value="classpath:hibernate.cfg.xml">
     </property>
</bean>
<!-- 定义事务管理器 -->
<bean id="transactionManager"
   class="org.springframework.orm.hibernate3.HibernateTransactionManager">
     <property name="sessionFactory">
         <ref local="sessionFactory" />
     </property>
</bean>

<bean id="baseTranProxy" abstract="true"
   class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <property name="transactionManager" ref="transactionManager" />
   <property name="transactionAttributes">
       <props>
           <!-- 指定那些方法参与事务 -->
           <prop key="save*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
          <prop key="delete*">PROPAGATION_REQUIRED</prop>
          <prop key="find*">PROPAGATION_REQUIRED</prop>
           <!-- 其它方法为只读事务,避免脏数据检查 -->
         <prop key="*">readOnly</prop>
         </props>
   </property>
</bean>
二,在要用到事务的bean中添加事务管理
<!--业务层实现类-->
<bean id="userSvr" class="com.jesun.service.impl.UserServiceImpl">
     <property name="userDao">
         <ref bean="userDAO"/>
    </property>
</bean>
<!--把业务层实现类添加事务管理,在实际的action(struts中)用到-->
<bean id="userSvr" parent="baseTranProxy">
      <property name="target" ref="userSvrImpl"/>
</bean>

此种配置需要在每个bean中去添加事务管理,对于一些大型系统似乎太繁琐,第二种配置可以解决这个问题:

第二种配置:

<!-- 定义hibernate的sessionFactory -->
<bean id="sessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="configLocation"
    value="classpath:hibernate.cfg.xml">
   </property>
</bean>
<!-- 定义事务管理器 -->
<bean id="transactionManager"
   class="org.springframework.orm.hibernate3.HibernateTransactionManager">
   <property name="sessionFactory">
    <ref local="sessionFactory" />
   </property>
</bean>

<bean id="transactionInterceptor"
   class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager">
         <ref bean="transactionManager" />
     </property>
   <property name="transactionAttributes">
    <props>
     <!-- 指定那些方法参与事务 -->
     <prop key="save*">PROPAGATION_REQUIRED</prop>
     <prop key="update*">PROPAGATION_REQUIRED</prop>
     <prop key="delete*">PROPAGATION_REQUIRED</prop>
     <prop key="find*">PROPAGATION_REQUIRED</prop>
     <!-- 其它方法为只读事务,避免脏数据检查 -->
     <prop key="*">readOnly</prop>
    </props>
   </property>
</bean>

<bean id="autoproxy"
   class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
   <!-- 可以是Service或DAO层(最好是针对业务层*Service) -->
   <property name="beanNames">
    <list><
     <!--表示配置所有以Svr结尾的Bean-->
     <value>*Svr</value>
   </list>
   </property>
    <property name="interceptorNames">
         <list>
             <value>transactionInterceptor</value>
      </list>
    </property>
</bean>

 

 

public void creatework(long processorid,long resourceid,Systeminfo si, Processorinfo pif, Osinfo oif, 
Networkinfo nif, Monitorinfo moif, Mouseinfo muif, 
Keyboardinfo kif, Memoryinfo mmif, Assetri ast, Resources rs, 
Resourcecost rsc, Resourcelocation rsl, Systeminfodomain sido, 
Networkdnsinfo nkif, Date acquisitiondate, Date warrantyexpiry, 
Date expirydate) { 
this.getHibernateTemplate().save(si); 
this.getHibernateTemplate().save(pif); 
this.getHibernateTemplate().save(oif); 
this.getHibernateTemplate().save(nif); 
this.getHibernateTemplate().save(moif); 
this.getHibernateTemplate().save(muif); 
this.getHibernateTemplate().save(kif); 
this.getHibernateTemplate().save(mmif); 
this.getHibernateTemplate().save(rs); 


在一个创建页面中提交后要创建好几条数据 为了保存数据完整性需要配置事务,此方法 还不能分开创建,如果一个失败要全部回滚,我已经配置了 但就是不管用 望指点 下面是spring的配置   
第一种 
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory"> 
<ref bean="sessionFactory"/> 
</property> 
</bean> 
<!-- 那些类那些方法使用事务 --> 
<aop:config> 
<aop:pointcut id="allManagerMethod" expression="execution(* hotlong.asset.service.*.*(..))"/> 
<aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/> 
</aop:config> 

<!-- 事务的传播特性 --> 
<tx:advice id="txAdvice" transaction-manager="transactionManager"> 
<tx:attributes> 
<tx:method name="create*" propagation="REQUIRED"/> 
<tx:method name="update*" propagation="REQUIRED"/> 
<tx:method name="del*" propagation="REQUIRED"/> 
<tx:method name="modify*" propagation="REQUIRED"/> 
<tx:method name="*" propagation="REQUIRED" read-only="true"/> 
</tx:attributes> 
</tx:advice> 
第二种   
<bean id="transactionManager" 
class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory" ref="sessionFactory" /> 
</bean> 
<bean id="baseTransactionProxy" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" 
abstract="true"> 
<property name="transactionManager" ref="transactionManager" /> 
<property name="transactionAttributes"> 
<props> 
<prop key="persist*"> 
PROPAGATION_REQUIRED,-Exception 
</prop> 
<prop key="remove*"> 
PROPAGATION_REQUIRED,-Exception 
</prop> 
<prop key="insert*">PROPAGATION_REQUIRED</prop> 
<prop key="create*">PROPAGATION_REQUIRED</prop> 
<prop key="add*">PROPAGATION_REQUIRED</prop> 
<prop key="save">PROPAGATION_REQUIRED</prop> 
<prop key="update*">PROPAGATION_REQUIRED</prop> 
<prop key="edit*">PROPAGATION_REQUIRED</prop> 
<prop key="del*">PROPAGATION_REQUIRED</prop> 
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="disPlay*">PROPAGATION_REQUIRES_NEW</prop> 
<prop key="changeState*">PROPAGATION_REQUIRED</prop> 
</props> 
</property> 
</bean> 
结果都一样 有的创建成功了 有的创建失败了 期待指点啊 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
配置Java项目使用SSH(Secure Shell)的步骤如下: 1. 下载和安装Java开发工具(如Eclipse或IntelliJ IDEA)。 2. 配置Java环境变量,确保Java开发工具可以找到Java的安装路径。 3. 创建一个新的Java项目。 4. 导入SSH的相关库,包括SSH框架(如Spring、Hibernate或MyBatis)的JAR文件,以及SSH所依赖的其他库文件。 5. 在项目中创建Java类,用于配置SSH的相关信息。这些信息包括数据库连接、Spring配置和Hibernate或MyBatis的配置。 6. 配置数据库连接,包括数据库的URL、用户名和密码等。 7. 配置Spring框架,将Spring配置文件引入项目,并配置各个类、接口和Bean的依赖关系。 8. 配置Hibernate或MyBatis,根据项目的需要选择其中一种配置方式。配置文件需要包括实体类(Entity)、映射文件(Mapping)和数据库表之间的关联关系。 9. 编写业务逻辑代码,包括处理请求、访问数据库、处理事务等。 10. 测试SSH项目,通过启动项目并发送请求来验证配置是否正确。可以使用浏览器、Postman或其他HTTP客户端发送HTTP请求。 11. 根据测试结果进行调试和排错,可能需要修改Java类、配置文件或数据库连接等。 12. 在项目开发完成后,可以将项目打包成WAR或JAR文件,并部署到服务器上进行线上运行。 配置SSH项目可能会根据具体情况有所不同,以上步骤仅为一般性指导,具体配置过程可能因项目需求和使用的SSH框架而有所区别。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值