5 minutes with – Jpa transaction

Many times, and in many classes, the access to the database should be done with transaction support, especially if you are writing in.

If you are using Spring, you can access the Transaction Manager supported by it.  In this post we’ll look inside this in classic web example.

The spring annotation to regulate this function is @Transactional. You can find all reference here.

In the follow example, I’ll show you an insert operation (from normal CRUD interface) with transaction support.

The Spring configuration file

<?xml version="1.0" encoding="windows-1252"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

  <!-- Add Transaction support -->
  <bean id="myTxManager"
     class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="emf"/>
  </bean>

  <!-- Use @Transaction annotations for managing transactions -->
  <tx:annotation-driven transaction-manager="myTxManager" />

  ...

  <!-- Add JPA support -->
	<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="OrderPU"/>
		<property name="dataSource" ref="dataSource"/>
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="showSql" value="true"/>
				<property name="generateDdl" value="false"/>
				<property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect"/>
			</bean>
		</property>
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
	    </property>
	</bean>

	<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">-->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
		<property name="url" value="jdbc:derby:C:/eclipse-Mule3.0/workspace/SampleWebJpaSpring/derbyDB"/>
		<property name="username" value=""/>
		<property name="password" value=""/>
	</bean>
</beans>

In the above snippet take a look to “myTxManager”.

In the Dao control class we have to define the persist method as “transactional” method

@Transactional (isolation=Isolation.READ_UNCOMMITTED,
                propagation=Propagation.REQUIRED,
                rollbackFor=Exception.class)
    public void persist(Order order) {
        em.persist(order);
    }

A list of the complete annotations parameters is at official Spring web site. Here a little summary of these.

Isolation

DEFAULT
          Use the default isolation level of the underlying datastore.
READ_COMMITTED
          A constant indicating that dirty reads are prevented; non-repeatable reads and phantom reads can occur.
READ_UNCOMMITTED
          A constant indicating that dirty reads, non-repeatable reads and phantom reads can occur.
REPEATABLE_READ
          A constant indicating that dirty reads and non-repeatable reads are prevented; phantom reads can occur.
SERIALIZABLE
          A constant indicating that dirty reads, non-repeatable reads and phantom reads are prevented.

Propagation

MANDATORY
          Support a current transaction, throw an exception if none exists.
NESTED
          Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
NEVER
          Execute non-transactionally, throw an exception if a transaction exists.
NOT_SUPPORTED
          Execute non-transactionally, suspend the current transaction if one exists.
REQUIRED
          Support a current transaction, create a new one if none exists.
REQUIRES_NEW
          Create a new transaction, suspend the current transaction if one exists.
SUPPORTS
          Support a current transaction, execute non-transactionally if none exists.

And now the control class with persist method.

package it.sample.dao;
import it.sample.data.Order;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
 
@Component
public class OrderDao {
 @PersistenceContext
    private EntityManager em;
 
    // Stores a new Order:
 @Transactional (isolation=Isolation.DEFAULT,
                 propagation=Propagation.REQUIRED,
                 rollbackFor=Exception.class)
    public void persist(Order order) throws Exception {
        em.persist(order);
        throw new Exception("Test Transaction rollback");
    }
}

Inside the method there’s an exception which cause the rollback of the order inserted into database.

Advertisements

6 thoughts on “5 minutes with – Jpa transaction

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s