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!
Related
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>
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.
While reading through Spring transaction documentation I see that it supports both Global transactions and Local transactions.
In simple terms what is global transaction and what is local transaction?
What are the advantages of one over the other? What are the appropriate uses of them?
If I use the following configuration – does it mean it is a local transaction?
<tx:annotation-driven transaction-manager="transManager" />
<bean id="transManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
I tried searching both in Google and Stackoverflow, but did not get any resources explaining the same in simple terms.
Actually there are plenty of resources answering your first two questions, for example Spring Documentation explains what local and global transaction is and depicts their differences in chapter 9.2 Motivation. In few words:
Global Transaction is an application server managed transaction, allowing to work with different transactional resources (this might be two different database, database and message queue, etc)
Local Transaction is resource specific transaction (for example Oracle Transactions) and application server has nothing to do with them.
(the same chapter explains the pros and cons of each of them very well and much better then I could explain, so I suggest you to give a closer look)
Answering your later question. The documentation says that JpaTransactionManager is capable for processing global transactions, so by looking at the piece of presented code it's hard to say if it's local or global transaction. The same documentation says that local single-resource transaction DataSourceTransactionManager should be used instead.
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.
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>