How do I implement my own #Tranactional aware service in Spring - java

I'm writing an app that may talk to multiple database and web services. I'd like to use Spring's #Transactional annotation so that a failure in any one can rollback them all.
I'm not clear about how I should do this, and I can't find any examples of it either after searching.
One thought I have is to create a bean that is a custom aspect and use that to intercept the methods, adding my own custom code to rollback problems. But I'm sure there must be a way to do this in a standardised fashion.
Thank you!
Alex

The most straightforward way to implement distributed transactions is JTA, but I don't think it's feasible in your case, because you also need to cover web services.
However, you can implement a "best effort" solution manually by registering TransactionSynchronizations for your transactional resources. This way you can integrate them with #Transactional.
See TransactionSynchronizationManager.

you should have something like below declared in your spring config xml for each of the datasource to be able to use #Transactional in your application:
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

Related

Proxy of Proxy being created in Spring

Is DefaultAutoProxyCreator needed if tx:annotation-driven is already enabled ?
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<property name="proxyTargetClass" value="true" />
</bean>
<tx:annotation-driven proxy-target-class="true"/>
It seems when there are both of them enabled, then proxy of proxies start getting created and starts failing.
Having only tx-annotation enabled, I have disabled spring-aspect and cglib also in maven dependencies. Do I need to have cglib even in Spring 4 for class based proxies like above ?
Spring version : 4.0.6
As far as I understand, you don't really need the explicit DefaultAdvisorAutoProxyCreator unless you have specific Advisors that you are using for cross cutting purpose - if so I feel that an #AspectJ approach may be cleaner.
Also, disabling cglib explicitly does not have any effect, Spring comes packaged with its own copy of CGLIB.

Can a Spring Batch job bean be lazily initialized?

In Spring, beans can be configured to be lazily initialized. Spring Batch jobs are also (Spring-managed) beans. That is, when I configure something like
<sb:job id="dummyJob" job-repository="jobRepository">
<sb:step id="dummyStep">
<sb:tasklet ref="dummyTasklet" />
</sb:step>
</sb:job>
I actually configure a new (Job-typed) bean inside the Spring container.
My issue is I really want my Job beans to be lazily initialized. As they are regular Spring-managed beans, I'd expect I can instruct the Spring context to make them lazy. This is because I have a large number of beans and there are many cases in which, during one execution of my Spring-based application, I only run one job.
But there's no lazy-init property I can set on my <sb:job... \> configuration. Is there any way I can force lazy initialization? If I configure my <beans\> root with default-lazy-init="true", will this also apply to the Job beans?
You have two options here:
Configure your job manually. This would allow you to use the regular lazy-init attributes Spring exposes.
Use the JobScope now available in Spring Batch 3. Spring Batch 3 will be available soon, but the JobScope was available in the last milestone.
Just to elaborate on Michael Minella's answer.
I had a similar requirement to lazy initialize the job repository.
I am working with Spring Batch 2.1.9.
The following is working for me.
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
lazy-init="true">
<property name="dataSource" ref="jobDataSource"/>
<property name="transactionManager" ref="jobTransactionManager"/>
</bean>
Note one pitfall I had run into: do not set the databaseType i.e. avoid the following:
<property name="databaseType" value="SQLSERVER"/>
This is bad because it disable the auto-discovery of the database type and breaked my JUnits that works on H2.

working with JTATransactionManager in spring?

I am trying to use JtaTransactionManager in spring/hibernate. I have below configuration.
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransactionName" value="java:comp/UserTransaction"></property>
</bean>
Now can i mark my service methods with #Transactional ? or do i need any extra configuration to use #Transactional ? do i need to add ?
An annotation is nothing more then metadata, so only slapping an annotation on there and expect it to magically work isn't going to happen.
To make #Transactional work you need to tell spring that you want to use annotation to drive your transactions. For this add the <tx:annotation-driven /> tag to your configuration.
However that probably isn't going to be all there is needed as you also need to configure hibernate appropriately for JTA.
A small tip instead of defining the bean, use the shorter <tx:jta-transaction-manager />. This will do some detection on which app server you are running and configure the appropriate transaction manager for you. See http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-application-server-integration for more information.

Can Spring's LocalContainerEntityManagerFactoryBean be used in a J2SE environment?

I'm using Spring in Glassfish and I have the need to configure it so it also works outside of the container, mainly for development purposes.
What I'm uncertain of, and couldn't find the answer to, was whether I can use the LocalContainerEntityManagerFactoryBean class without a container.
From its name, LocalContainer, it seems I can but in the docs it says:
FactoryBean that creates a JPA
EntityManagerFactory according to
JPA's standard container bootstrap
contract
so I'm uncertain about this issue.
Thanks,
Ittai
I just wanted to note that Spring supports running the JPA stuff outside of a container, and doesn't require anything in the way of a transaction manager. The question to ask is whether you are using Spring's declarative transaction management (e.g., "#Transactional").
If you are, then you need to provide an implementation of "PlatformTransactionManager." Here still, you do NOT need to use full on JTA support (as provided by Atomikos in the above example. YOu can simply use a JpaTransactionManager instance (which expects a reference to the entity manager factory) provided you are not doing anything with "XA" etc. If you are doing XA, then Atomikos, or Bitronix or any of a number of other options are just fine. You might look at this example http://blog.springsource.com/2011/08/15/configuring-spring-and-jta-without-full-java-ee/ which demonstrates how to use JTA (with JPA and JMS, for example).
So, reiterating, if you're just doing simple JPA (connecting to one database) then you don't need JTA, and you definitely don't need GlassFish. If you need XA, then you can still use a third party JTA provider as the responder above suggested, and you still don't need Glassfish.
Finally, if you truly wish to maintain both GlassFish + JTA, and a separate JPA that works only locally for rapid development on a faster container, you might consider the imminent Spring 3.1, which features "profiles" to allow you to conditionally define beans per environment (e.g., "production," or "dev," or "cloud," or whatever you'd like.)
Yes, it's possible, but you need to provide a transaction manager (like Atomikos). The rest of the configuration is the same.
This is an example:
<bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"
init-method="init" destroy-method="shutdownForce">
</bean>
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close" depends-on="userTransactionService">
<property name="forceShutdown" value="true" />
</bean>
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"
depends-on="userTransactionService">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"
depends-on="userTransactionService">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
....
</bean>

when using #transactional do i need to use jpatemplate/hibernatetemplate?

when using #transactional do i need to use jpatemplate/hibernatetemplate ?
No, you don't. Spring has a built-in transaction manager that can be used for simple transactions, e.g. if you don't need to track transactions across more than one DataSource. The configuration should be as simple as this:
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Where the bean named "dataSource" is some DataSource bean configured elsewhere in your XML file.
However if you're using JPA or Hibernate, it would be a good idea to use the JPATransactionManager or HibernateTransactionManager, respectively.
If you really wanted to you could also use JTA, which is Sun's standard transaction implementation. I think the spring class is called JTATransactionManager.
Using transaction managers other than Spring's out-of-the-box one (the one defined in the XML config above) will give you the ability to use transactions across multiple DataSources.
The answer depends on the what version of Hibernate you are using. With later versions the simple answer is no you don't need the templates. See here for a comprehensive discussion:
http://blog.springsource.com/2007/06/26/so-should-you-still-use-springs-hibernatetemplate-andor-jpatemplate/
I came across an article that explains the process of implementing TxManager using #Transactional in depth. If you are interested, you can check this article here. I tried and this works!

Categories