Section 7.1. Programmatic Transactions

team bbl


7.1. Programmatic Transactions

Like most other services in Spring, you can use transactions programmatically or declaratively. When you're using a new service, it often makes sense to understand that service programmatically within a method before you break it out as a declarative service.

Sometimes, you want to hide services, and Spring certainly makes it easy to do so. Other times, you want to be explicit, such as when transactional logic is the central job of your method. Spring makes it easy to do transaction logic programmatically.

7.1.1. How do I do that?

You'll use the same mechanism for transactions as you do for JDBC: templates. For programmatic transactions, you'll use a TRansactionTemplate. You'll put all of the code in the transaction body that you want to execute together.

In this case, imagine that a customer wants to cancel her current reservation and make a new one for later in the week. If the new reservation fails for any reason, she wants to keep her old one. You'll add a method to RentABike called transferReservation. It will delete an existing reservation and create a new one (Example 7-1).

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( );     } }

You'll need to set up the transaction strategy for the template in the context, and create the accounts and the RentABike (Example 7-2).

Example 7-2. RentABike-servlet.xml
<beans>     <bean  >         <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  >         <property name="sessionFactory">             <ref local="sessionFactory"/>         </property>     </bean>     <bean  >             <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  >             <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>

Take special care. Because you are using MySQL as the database for this example, you'll need one final step to get it to work. In order to support transactions, you have to mark your tables in MySQL as InnoDB type, which lets MySQL be transactional, with full ACID semantics.


Note: ACID stands for atomic, consistent, isolated and durable. All transactions need these properties.

7.1.2. What just happened?

A template is a simple, default transaction-handling method. All of the boilerplate code is in the template. You just have to implement the method that does all of the work. It will either all succeed or roll back.

You're looking for two things: a pluggable architecture, and leverage. Of course, Hibernate transactions need only a command or two. Think about a native implementation. If you wanted to replace the Hibernate transactions with JTA transactions (to coordinate with changes in another database), you'd have to replace your implementation throughout your code, and you'd have to do much more work.

With your Spring implementation, you need only change configuration. The template gives you exactly what you want: a place to specify what needs to happen together successfully for the transaction to succeed.

    team bbl



    Spring. A developer's Notebook
    Spring: A Developers Notebook
    ISBN: 0596009100
    EAN: 2147483647
    Year: 2005
    Pages: 90

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net