if some one can explain what this annotation do and when exactly we use it :
#Transactional(propagation=Propagation.REQUIRED)
Thanks
If you need a laymans explanation of the use beyond that provided in the Spring Docs
Consider this code...
class Service {
#Transactional(propagation=Propagation.REQUIRED)
public void doSomething() {
// access a database using a DAO
}
}
When doSomething() is called it knows it has to start a Transaction on the database before executing. If the caller of this method has already started a Transaction then this method will use that same physical Transaction on the current database connection.
This #Transactional annotation provides a means of telling your code when it executes that it must have a Transaction. It will not run without one, so you can make this assumption in your code that you wont be left with incomplete data in your database, or have to clean something up if an exception occurs.
Transaction management is a fairly complicated subject so hopefully this simplified answer is helpful
When the propagation setting is PROPAGATION_REQUIRED, a logical transaction scope is created for each method upon which the setting is applied. Each such logical transaction scope can determine rollback-only status individually, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, all these scopes will be mapped to the same physical transaction. So a rollback-only marker set in the inner transaction scope does affect the outer transaction's chance to actually commit (as you would expect it to).
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html
In Spring applications, if you enable annotation based transaction support using <tx:annotation-driven/> and annotate any class/method with #Transactional(propagation=Propagation.REQUIRED) then Spring framework will start a transaction and executes the method and commits the transaction. If any RuntimeException occurred then the transaction will be rolled back.
Actually propagation=Propagation.REQUIRED is default propagation level, you don't need to explicitly mentioned it.
For further info : http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations
To understand the various transactional settings and behaviours adopted for Transaction management, such as REQUIRED, ISOLATION etc. you'll have to understand the basics of transaction management itself.
Read Trasaction management for more on explanation.
Related
I am trying to understand the propagation attribute of #Transactional annotation in Spring Data JPA. I have read enough theory. But I do not understand(nor can I find anywhere on internet) the real-life scenario where I need to use the PROPAGATION_REQUIRED in place of PROPAGATION_REQUIRES_NEW. I understand the theory that PROPAGATION_REQUIRED can utilize the existing transaction and PROPAGATION_REQUIRES_NEW will start a new transaction each time. But I could not understand two things -
How does it matter to me as a programmer? or in which used cases one is preferred over other?
Is the "TRANSACTION" we are talking about is a spring transaction or a database transaction
In Spring, if a method that is annotated with #Transactional calls another method annotated with #Transactional, the transaction is started at the beginning of the first method and commited after the second method is finished.
Requiring a new transaction can be helpful, if you have a sequence of methods that are transactional but you want to commit a transaction half way through the sequence.
Or maybe you have a method that should always open it's own transaction and you want to make sure it does so, even if it is called by another transactional method.
If I have nested bean methods which just fetching data from the database. (i.e GET API). So will it be beneficial to mark all bean methods as TransactionAttributeType.NOT_SUPPORTED? Will it help in increase in performance as JTA is not managing any transaction for this?
This is exactly the purpose of using NOT_SUPPORTED, to increase performance. Infact as stated by Oracle:
NotSupported Attribute
If the client is running within a transaction and invokes the
enterprise bean’s method, the container suspends the client’s
transaction before invoking the method. After the method has
completed, the container resumes the client’s transaction.
If the client is not associated with a transaction, the container does
not start a new transaction before running the method.
Use the NotSupported attribute for methods that don’t need
transactions. Because transactions involve overhead, this attribute
may improve performance.
So, it is a perfect fit for all the select or find business methods, which purpose is maybe to fill a data table on screen.
NOT_SUPPORTED is useful if there is a processing that would cause an exception if invoked with transaction context. For example invoking stored procedure containing DDL code withing context of XA processing will cause an exception to occur. If changing stored procedure is not an option use NOT_SUPPORTED attribute as work around and suspend the transaction prior to invocation of method containing problematic stored procedure.
If transaction roll back is allowed in read only transaction use SUPPORTS , if transaction roll back is not allowed in read only transaction use NOT_SUPPORTED.
This article says:"No, it doesn't make sense to use the NOT_SUPPORTED transaction propagation for read-only queries". It's written Vlad Mihalcea who is a JPA expert.
Does TransactionAttributeType.NOT_SUPPORTED make sense for retrieving entities?
I have a web application that uses Spring NamedJDBCTemplate, and all the calls to database are select statements.
In this case should i use #Transactional in my service class that calls the DAO class that inturn fires select statements to DB.
According to Transaction statergies listing 10 suggests to not use #Transactional for reads. Will i be bringing an overhead by using #Transactional and also i dont want to miss the AOP advises that i can bring in for #Transactional in future.
Yes, you should always access the database from inside a transaction. Not doing it will in fact create a transaction for every select statements.
Transactions aren't just useful for atomicity of updates. They also provide isolation guarantees. For example, (depending on the isolation level) reading the same row twice in a single transaction can return you the same data, and thus make sure you don't have incoherences in the read data. Doing it with multiple transactions won't provide any such guarantee.
I think the best way is to use #Transactional and set it as Supported not Required for such service
in this way if your service call outside a transaction it will not start a Transaction and if it calls from other service that is Transactional and already start a transaction it will participate in that transaction.
for example think that one service required to call two services in first one some data will inserted or updated and other one is just a select that return those data if these two service don't participate in single transaction the second service will not return data because the transaction start in calling service not committed yet .
I'm having a difficult time understanding Spring Transactions. First off, I am trying to use as little of Spring as possible. Basically, I want to use #Transactional and some of its injection capabilities with JPA/Hibernate. My transactional usage is in my service layer. I try to keep them out of test cases. I use CTW and am spring-configured. I have component scan on the root of my packages right now. I also am using Java configuration for my datasource, JpaTransactionManager, and EntityManagerFactory. My configuration for the JpaTransactionFactory uses:
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
I do not use #EnableTransactionManagement.
Unfortunately, I'm having a hard time understanding the rules for #Transactional and can't find an easy page that describes them simply. Especially with regards to Session usage. For example, what if I want to use #Transactional on a class that does not have a default no-arg constructor?
The weirdest problem I'm having is that in some of the POJO service classes Transacitonal works great while in others I can see the transactions being created but operations ultimately fall saying that there is "no session or the session has been closed". I apologize for not having code to reproduce this, I can't get it down to a small set. This is why I am looking for the best resources so I can figure it out myself.
For example, I can have a method that gets a lazily fetched collection of children, iterates through it and puts it into a Set and returns that set. In one class it will work fine while in another class also marked with #Transactional it will fail while trying to iterate through the PersistentSet saying that there is no session (even though there IS a transaction).
Maybe this is because I create both of these service objects in a test case and the first one is somehow hijacking the session?
By the way, I have read through the spring source transaction documents. I'm looking for a clear set of rules and tips for debugging issues like this. Thanks.
Are you sure you loaded your parent entity in the scope of the very transaction where you try to load the lazy children? If it was passed in as parameter for example (that is, loaded from outside your #Transactional method) then it might not be bound to a persistence context anymore...
Note that when no #Transactional context is given, any database-related action may have a short tx to be created, then immediately closed - disabling subsequent lazy-loading calls. It depends on your persistence context and auto-commit configurations.
To put it simply, the behaviour with no transactional context being sometimes unexpected, the ground rule is to always have one. If you access your database, then you give yourself a well-defined tx - period. With spring-tx, it means all your #Repository's and #Services are #Transactional. This way you should avoid most of tx-related issues.
I am using Spring declarative database transaction management using the #Transactional annotation on my java methods.
In one case, I would like to explicitly commit the current transaction (the one wrapping the currently executing method) prior to the method returning.
How can this be done?
I have tried auto wiring the current HibernateTransactionManager from the spring context and using that to commit, but it doesn't commit the transaction.
The code I have tried is:
transactionManager.commit(transactionManager
.getTransaction(new DefaultTransactionDefinition()));
i have not tried but you might be able to do this with some trick which i can think of
get TransactionStatus using TransactionAspectSupport.currentTransactionStatus()
inject transaction manager to your bean (assuming you are using hibernate)
try to invoke doCommit(DefaultTransactionStatus status) in transaction manager.
try this out not sure it will work or not because as per spring doc
transaction
You are strongly encouraged to use the declarative approach to
rollback if at all possible. Programmatic rollback is available should
you absolutely need it, but its usage flies in the face of achieving a
clean POJO-based architecture.
i have not tested but if you set setRollbackOnly to TransactionStatus that might also do the job.
The nested transaction, that being seeked above, can be achieved using REQUIRES_NEW propogation, BUT by taking care of self invocation, as explained here