EJB 3 Transaction attribute for read only method - methods

I have a method that returns lot of data, should I use #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) for this method. The method perform a JPA query an loads the full content of a table (about 1000 rows).

The client to this method - is that already in a transaction? When you use NotSupported the caller transaction will be suspended. If not I would say, just put Never as the transaction type. Never is better since callers know they are not supposed to call this method from inside a transaction. A more straight forward contract.
We always use Never for methods that do more processing so that developers are aware right off the bat not to call if they are involved in a transaction already. Hope it helps.

I would care to disagree as it seldom happens that user is not in a transaction in almost all the systems. The best approach is to use NOT SUPPORTED so that the transaction is suspended if the caller is in any transaction already. NEVER is troublesome unless you have a series of calls which are all in NO TRANSACTION scope. In short, NOT SUPPORTED is the type one should use.

As far as I know (at least this is the case with Hibernate), you cannot use JPA outside of a transaction as the entity manager's lifecycle is linked to the transaction's lifecycle. So the actual method that does the query must be transactional.
However, you can set it to TransactionAttributeType.REQUIRES_NEW; this would suspend any existing transaction, start a new one, and stop it when the method returns. That means all your entities would be detached by the time they reach the caller, which is what it sounds like you're trying to achieve.
In more complex systems, it pays to completely separate your data layer from your business layer and create a new set of object. Your method will then call the JPA query, then use the entities returned to populate objects from your business layer, and return those. That way the caller can never get their hands on the actual JPA entities and you are free to do in your data layer what you want, since now it's just an implementation detail. (Heck, you could change the database call to a remote API call and your caller wouldn't have to know.)

Related

Is it possible to make some action in a new Spring trascation before a user stars work with it?

I have Spring Boot JPA application.
An application user asks a new transaction from time to time.
I'd like to execute some action on a db connection that is related with the transaction just BEFORE the use can work with that transaction.
"Just BEFORE" means the action has been completed before the first statement of a method annotated with #Transactional is executed.
The action is an execution of a stored procedure with params depend on the current application user.
Application uses work with DB under a technical account.
Thank you in advance
First solution:
Put all in #Transacional annotated method, where your pre-transaction, however this may sound weird, part goes first.
This first part may perform any action and maybe throw en exception if anything goes wrong, thus forcing the transaction to roll back. This may be a #Repository method, a #Query annotated one if needed (like Josh Pospisil suggests) or whatever.
Second solution (I would prefer):
Put 3 method calls in your #RestController's method: first - determining the user, second - performing your pre-transactional action using this user's data, third - the actual #Transacional method doing the job.

Real life scenarios for Transaction propagations

There are various transaction propagations like
REQUIRED - This is the case for DML operation.
SUPPORTS - This is the case for querying database.
MANDATORY - ?
REQUIRES_NEW - ?
NOT_SUPPORTED - ?
NEVER - ?
NESTED - ?
What are some real life scenarios for these transaction propagations? Why these are perfect fit into that situation?
There are various usages and there is no simple answer but I'll try to be the most explainatory
MANDATORY (expecting transaction): Typically used when you expect that any "higher-context" layer started the transaction and you only want to continue in it. For example if you want one transaction for whole operation from HTTP request to response. Then you start transaction on JAX-RS resource level and lower layers (services) require transaction to run within (otherwise exception is thrown).
REQUIRES_NEW (always create new transaction): This creates a new transaction and suspends the current one if any exists. From above example, this is the level you set on your JAX-RS resource for example. Or generally if your flow somehow changes and you want to split your logic into multiple transactions (so your code have mutliple logic operations that should be separated).
REQUIRED (continue in transaction or create if needed): Some kind of mix between MANDATORY and REQUIRES_NEW. In MANDATORY you expect that the transaction exists, for this level you hope that it exists and if not, you create it. Typically used in DAO-like services (from my experience), but it really depends on logic of your app.
SUPPORTS (caller decides whether to not/run in transaction): Used if want to use the same context as caller (higher context), if your caller was running in transaction, then you run in too. If it didn't, you are also non-transactional. May also be used in DAO-like services if you want higher context to decide.
NESTED (sub-transaction): I must admit I didn't use this one in real code but generally you create a real sub-transaction that works as some kind of checkpoint. So it runs in the context of "parent" transaction but if it fails it returns to that checkpoint (start of nested transaction). This may be useful when you require this kind of logic in your application, for example if you want to insert large number of items to the database, commiting valid ones and keeping track of invalid ones (so you can catch exception when nested transaction fails but can still commit the whole transaction for valid ones)
NEVER (expecting there is no transaction): This is the case when you want to be sure that no transaction exists at all. If some code that runs in transaction reaches this code, exception is thrown. So typically this is for cases completely opposite to MANDARTORY. E.g. when you know that no transaction should be affected by this code - very likely because the transaction should not exist.
NOT_SUPPORTED (continue non-transactionally): This is weaker than NEVER, you want the code to be run non-transactionally. If somehow you enter this code from context where transaction is, you suspend this transaction and continue non-transactionally.
From my experience, you very often want one business action to be atomic. Thus you want only one transaction per request/... For example simple REST call via HTTP that does some DB operations all in one HTTP-like transaction. So my typical usage is REQUIRES_NEW on the top level (JAX-RS Resource) and MANDATORY on all lower level services that are injected to this resource (or even lower).
This may be useful for you. It describes how code behave with given propagation (caller->method)
REQUIRED: NONE->T1, T1->T1
REQUIRES_NEW: NONE->T1, T1->T2
MANDATORY: NONE->Exception, T1->T1
NOT_SUPPORTED: NONE->NONE, T1->NONE
SUPPORTS: NONE->NONE, T1->T1
NEVER: NONE->NONE, T1->Exception

Inject Session object to DAO bean instead of Session Factory?

In our application we are using Spring and Hibernate.
In all the DAO classes we have SessionFactory auto wired and each of the DAO methods are calling getCurrentSession() method.
Question I have is why not we inject Session object instead of SessionFactory object in prototype scope? This will save us the call to getCurrentSession.
I think the first method is correct but looking for concrete scenarios where second method will throw errors or may be have bad performance?
When you define a bean as prototype scope a new instance is created for each place it needs to be injected into. So each DAO will get a different instance of Session, but all invocations of methods on the DAO will end up using the same session. Since session is not thread safe it should not be shared across multiple threads this will be an issue.
For most situations the session should be transaction scope, i.e., a new session is opened when the transaction starts and then is closed automatically once the transaction finishes. In a few cases it might have to be extended to request scope.
If you want to avoid using SessionFactory.currentSession - then you will need to define your own scope implementation to achieve that.
This is something that is already implemented for JPA using proxies. In case of JPA EntityManager is injected instead of EntityManagerFactory. Instead of #Autowired there is a new #PersistenceContext annotation. A proxy is created and injected during initialization. When any method is invoked the proxy will get hold of the actual EntityManager implementation (using something similar to SessionFactory.getCurrentSession) and delegate to it.
Similar thing can be implemented for Hibernate as well, but the additional complexity is not worth it. It is much simpler to define a getSession method in a BaseDAO which internally call SessionFactory.getCurrentSession(). With this the code using the session is identical to injecting session.
Injecting prototype sessions means that each one of your DAO objects will, by definition, get it's own Session... On the other hand SessionFactory gives you power to open and share sessions at will.
In fact getCurrentSession will not open a new Session on every call... Instead, it will reuse sessions binded to the current session context (e.g., Thread, JTA Transacion or Externally Managed context).
So let's think about it; assume that in your business layer there is a operation that needs to read and update several database tables (which means interacting, directly or indirectly, with several DAOs)... Pretty common scenario right? Customarily when this kind of operation fails you will want to rollback everything that happened in the current operation right? So, for this "particular" case, what kind of strategy seems appropriate?
Spanning several sessions, each one managing their own kind of objects and bound to different transactions.
Have a single session managing the objects related to this operation... Demarcate the transactions according to your business needs.
In brief, sharing sessions and demarcating transactions effectively will not only improve your application performance, it is part of the functionality of your application.
I would deeply recommend you to read Chapter 2 and Chapter 13 of the Hibernate Core Reference Manual to better understand the roles that SessionFactory, Session and Transaction plays within the framework. It will also teach will about Units of work as well as popular session patterns and anti-patterns.

Grails service transactional behaviour

In a Grails app, the default behaviour of service methods is that they are transactional and the transaction is automatically rolled-back if an unchecked exception is thrown. However, in Groovy one is not forced to handle (or rethrow) checked exceptions, so there's a risk that if a service method throws a checked exception, the transaction will not be rolled back. On account of this, it seems advisable to annotate every Grails service class
#Transactional(rollbackFor = Throwable.class)
class MyService {
void writeSomething() {
}
}
Assume I have other methods in MyService, one of which only reads the DB, and the other doesn't touch the DB, are the following annotations correct?
#Transactional(readOnly = true)
void readSomething() {}
// Maybe this should be propagation = Propagation.NOT_SUPPORTED instead?
#Transactional(propagation = Propagation.SUPPORTS)
void dontReadOrWrite() {}
In order to answer this question, I guess you'll need to know what my intention is:
If an exception is thrown from any method and there's a transaction in progress, it will be rolled back. For example, if writeSomething() calls dontReadOrWrite(), and an exception is thrown from the latter, the transaction started by the former will be rolled back. I'm assuming that the rollbackFor class-level attribute is inherited by individual methods unless they explicitly override it.
If there's no transaction in progress, one will not be started for methods like dontReadOrWrite
If no transaction is in progress when readSomething() is called, a read-only transaction will be started. If a read-write transaction is in progress, it will participate in this transaction.
Your code is right as far as it goes: you do want to use the Spring #Transactional annotation on individual methods in your service class to get the granularity you're looking for, you're right that you want SUPPORTS for dontReadOrWrite (NOT_SUPPORTED will suspend an existing transaction, which won't buy you anything based on what you've described and will require your software to spend cycles, so there's pain for no gain), and you're right that you want the default propagation behavior (REQUIRED) for readSomething.
But an important thing to keep in mind with Spring transactional behavior is that Spring implements transaction management by wrapping your class in a proxy that does the appropriate transaction setup, invokes your method, and then does the appropriate transaction tear-down when control returns. And (crucially), this transaction-management code is only invoked when you call the method on the proxy, which doesn't happen if writeSomething() directly calls dontReadOrWrite() as in your first bullet.
If you need different transactional behavior on a method that's called by another method, you've got two choices that I know of if you want to keep using Spring's #Transactional annotations for transaction management:
Move the method being called by the other into a different service class, which will be accessed from your original service class via the Spring proxy.
Leave the method where it is. Declare a member variable in your service class to be of the same type as your service class's interface and make it #Autowired, which will give you a reference to your service class's Spring proxy object. Then when you want to invoke your method with the different transactional behavior, do it on that member variable rather than directly, and the Spring transaction code will fire as you want it to.
Approach #1 is great if the two methods really aren't related anyway, because it solves your problem without confusing whoever ends up maintaining your code, and there's no way to accidentally forget to invoke the transaction-enabled method.
Approach #2 is usually the better option, assuming that your methods are all in the same service for a reason and that you wouldn't really want to split them out. But it's confusing to a maintainer who doesn't understand this wrinkle of Spring transactions, and you have to remember to invoke it that way in each place you call it, so there's a price to it. I'm usually willing to pay that price to not splinter my service classes unnaturally, but as always, it'll depend on your situation.
I think that what you're looking for is more granular transaction management, and using the #Transactional annotation is the right direction for that. That said, there is a Grails Transaction Handling Plugin that can give you the behavior that you're looking for. The caveat is that you will need to wrap your service method calls in a DomainClass.withTransaction closure and supply the non-standard behavior that you're looking for as a parameter map to the withTransaction() method.
As a note, on the backend this is doing exactly what you're talking about above by using the #Transactional annotation to change the behavior of the transaction at runtime. The plugin documentation is excellent, so I don't think you'll find yourself without sufficient guidance.
Hope this is what you're looking for.

Why use service layer?

I looked at the example on http://solitarygeek.com/java/developing-a-simple-java-application-with-spring/comment-page-1#comment-1639
I'm trying to figure out why the service layer is needed in the first place in the example he provides. If you took it out, then in your client, you could just do:
UserDao userDao = new UserDaoImpl();
Iterator users = userDao.getUsers();
while (…) {
…
}
It seems like the service layer is simply a wrapper around the DAO. Can someone give me a case where things could get messy if the service layer were removed? I just don’t see the point in having the service layer to begin with.
Having the service layer be a wrapper around the DAO is a common anti-pattern. In the example you give it is certainly not very useful. Using a service layer means you get several benefits:
you get to make a clear distinction between web type activity best done in the controller and generic business logic that is not web-related. You can test service-related business logic separately from controller logic.
you get to specify transaction behavior so if you have calls to multiple data access objects you can specify that they occur within the same transaction. In your example there's an initial call to a dao followed by a loop, which could presumably contain more dao calls. Keeping those calls within one transaction means that the database does less work (it doesn't have to create a new transaction for every call to a Dao) but more importantly it means the data retrieved is going to be more consistent.
you can nest services so that if one has different transactional behavior (requires its own transaction) you can enforce that.
you can use the postCommit interceptor to do notification stuff like sending emails, so that doesn't junk up the controller.
Typically I have services that encompass use cases for a single type of user, each method on the service is a single action (work to be done in a single request-response cycle) that that user would be performing, and unlike your example there is typically more than a simple data access object call going on in there.
Take a look at the following article:
http://www.martinfowler.com/bliki/AnemicDomainModel.html
It all depends on where you want to put your logic - in your services or your domain objects.
The service layer approach is appropriate if you have a complex architecture and require different interfaces to your DAO's and data. It's also good to provide course grained methods for clients to call - which call out to multiple DAO's to get data.
However, in most cases what you want is a simple architecture so skip the service layer and look at a domain model approach. Domain Driven Design by Eric Evans and the InfoQ article here expand on this:
http://www.infoq.com/articles/ddd-in-practice
Using service layer is a well accepted design pattern in the java community. Yes, you could straightaway use the dao implementation but what if you want to apply some business rules.
Say, you want to perform some checks before allowing a user to login into the system. Where would you put those logics? Also, service layer is the place for transaction demarcation.
It’s generally good to keep your dao layer clean and lean. I suggest you read the article “Don’t repeat the DAO”. If you follow the principles in that article, you won’t be writing any implementation for your daos.
Also, kindly notice that the scope of that blog post was to help beginners in Spring. Spring is so powerful, that you can bend it to suit your needs with powerful concepts like aop etc.
Regards,
James

Resources