/**
作者: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事务(其主要原因可能是要适应不同数据库的改变),那么我们不得不用代码来代替目前的实现,那样我们可以完成更多的处理操作。
作者: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事务(其主要原因可能是要适应不同数据库的改变),那么我们不得不用代码来代替目前的实现,那样我们可以完成更多的处理操作。