pom.xml
This dependency is needed to allow transactions<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<scope>compile</scope>
</dependency>
Spring Context
In the spring configuration an entity manager is necessary (see Entity Manager blog entry)
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /><!-- Define a transaction manager so that the @TransactionConfiguration and @Transactional can be used -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Proxy Class
The above combination will allow spring to create proxy classes which create a transaction before passing into the @Transactional method. This means that because it is a proxy @Transactional doesn't work for any 'internal' call within the your class. Eg even if a method is public if it is called from within the same class it won't pass through the proxy and therefore won't have a transaction.
If this type of behaviour is required then the transactions can be wired using AOP and the transaction code is created at compile time rather than a runtime proxy.
Exception Handling
Normal exceptions can be caught using the normal try - catch but if the database isn't there at all then there is an exception generated in the proxy before the method code is called. The exception is a
org.springframework.transaction.CannotCreateTransactionException
To catch the exception within the same method as the actual database errors the transaction can be created a different way.
Programmatic Transactions
A programmatic transaction can be created using the TransactionTemplate in which case the TransactionException (CannotCreateTransactionException) can be caught in the same place.
try
{
transactionTemplate.execute(new TransactionCallbackWithoutResult()
{
@Override
protected void doInTransactionWithoutResult(final TransactionStatus status)
{
// Do something to the database here
}
});
}
catch (PersistenceException | TransactionException e)
{
LOG.error("Database Error", e);
}
There is also a TransactionCallback() which returns the object from the database whereas the one above doesn't do that.
The transactionTemplate can be created in spring configuration,
<property name="transactionTemplate">
<bean class="org.springframework.transaction.support.TransactionTemplate">
<constructor-arg ref="transactionManager" />
</bean>
</property>
No comments:
Post a Comment