[原创]Spring: A Developer's Notebook笔记和小结(19)

/**
作者:Willpower
来源:Rifoo Technology(
http://www.rifoo.com
时间:2006-03-26
备注:转载请保留以上声明
**/

本节主要讨论编程式事务(Programmatic Transactions)的概念。

和许多Spring的其他服务一样,我们可以使用编程式事务或声明式事务。有时,我们需要隐藏一些服务,让一些服务在后台去自动处理,Sprng可以很容易的做到这一点。另一些时候,我们又需要让服务是显式的,比如当事务逻辑是我们的方法中指定的。Spring使得我们可以很容易的以编程的方式来处理事务逻辑。

我们将使用和JDBC Template一样的机制来处理事务。对于编程式事务,我们要使用一个叫做TransactionTemplate的模板。我们会将需要同时执行的代码一起都放到事务体( transaction body)的代码中去。

在本例中,假设客户需要cancel掉她当前的预订信息并重新预订了一个新的,这个新的是比当前的要晚一周。如果这个新的预订处理因为某些原因失败了,那么客户希望能够保留那个旧的当前的预订信息。因此,我们给RentABike 添加一个方法transferReservation。 这个方法会删除一个现有的预订信息并创建一个新的。

Example 7-1. HibRentABike.java
public void transferReservation(final Reservation oldRes,
  final Reservation newRes) throws ReservationTransferException {
   
  TransactionTemplate template =
    new TransactionTemplate(this.transactionManager);
    template.setPropagationBehavior(
    TransactionDefinition.PROPAGATION_REQUIRED);
    try {
  template.execute(new TransactionCallbackWithoutResult( ) {
          protected void doInTransactionWithoutResult(
        TransactionStatus transactionStatus) {
               
        getHibernateTemplate( ).save(newRes);
        getHibernateTemplate( ).delete(oldRes);
        }
    });
  } catch (Exception ex) {
    throw new ReservationTransferException( );
  }
}


这里的save和delete两个操作是在一个事务中的。

下面,我们要在上下文中去创建一个事务策略,并创建RentABike和事务的关联以及连接用的账号 。代码如下:

Example 7-2. RentABike-servlet.xml
<beans>

  <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    <property name="dataSource"><ref local="dataSource"/></property>
        <property name="mappingResources">
          <list>
            <value>com/springbook/Bike.hbm.xml</value>
            <value>com/springbook/Customer.hbm.xml</value>
            <value>com/springbook/Reservation.hbm.xml</value>
            <value>com/springbook/LogEvent.hbm.xml</value>
          </list>
      </property>
      <property name="hibernateProperties">
          <props>
              <prop key="hibernate.dialect">
          net.sf.hibernate.dialect.MySQLDialect
        </prop>
              <prop key="hibernate.show_sql">false</prop>
          </props>
      </property>
    </bean>

 
<bean id="transactionManager" class="org.springframework.orm.
hibernate.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref local="sessionFactory"/>
    </property>
  </bean>


  <bean id="rentaBike" class="com.springbook.HibRentABike">
        <property name="storeName">
        <value>Bruce's Bikes</value>
    </property>
        <property name="sessionFactory">  
        <ref local="sessionFactory"/>
    </property>
        <property name="transactionManager">
          <ref local="transactionManager"/>
        </property>

  </bean>

  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
        <value>com.mysql.jdbc.Driver</value>
    </property>
        <property name="url">
        <value>jdbc:mysql://localhost/rentabike</value>
    </property>
        <property name="username"><value>bikestore</value></property>
  </bean>
</beans>


特别提醒:因为我们正在使用的是MySQL数据库,我们还需要一个额外的步骤来让它正常处理事务。要支持事务,我们需要将我们的MySQL表设置为InnoDB这种类型,这种类型使得MySQL能够支持事务,以及ACID的数据存储。(ACID的意思是:atomic, consistent, isolated and durable. 所有事务都需要这些属性。)

小结:
模板方式是简单的,并且是默认的事务处理方式。所有的样板文件代码都在一个模板里。我们仅仅需要实现这个方法去完成所有工作。要么全部都操作成功,要么全部都操作失败并一起回滚。

我们正在寻找两个东西:一个可插拔的架构和核心杠杆。当然,Hibernate事务仅仅只需要一到两行命令即可实现。考虑一个本地实现。如果想要用JTA事务来替换Hibernate事务(其主要原因可能是要适应不同数据库的改变),那么我们不得不用代码来代替目前的实现,那样我们可以完成更多的处理操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值