java - Whats the best practice around when to start a new session or transaction for batch jobs using spring/hibernate? -


I have set batch / cron jobs in java that call my service classes. I am using hibernate and spring also.

Originally the batch layer was always creating external transactions, and then the service will call a service to get the list of items from DB W / AD from the batch, then each item separately Call a service to process. There is a tx-advice set for rollback on any throwable for my service layer, so if there is an exception on the 5th object, then the first 4 objects are returned because they were all parts of the same transaction.

So I was thinking this external transaction made in the batch layer was unnecessary. I removed it, and now I call a service to get a list of items. Then call each other service to separate each item separately, and if one of those objects fails, then other people will still continue, because a new transaction / session for each service call. But the problem I am receiving here comes after getting a list of objects, when I give a service to process each object, if I try to get one from the property, then I am lazy Getting initialization error is because the session used to load that object

I thought that some options were available for getting a list of IDs in the job of batch and for a service Every ID passes and the service will retrieve the whole thing in that session and process it. Another person has to load the false lazy to the characteristics of that object, but it will load everything every time, even if nested characteristics Not required.

The way I was always basically / the external transaction around every batch job, and then make another transaction in the job of batch before each call of service for each person's processing ...

What is the best practice for something like this?

OK I would say that you have listed every possible option. This will keep your session alive in all transactions, but it is difficult to implement it properly. It is so difficult that it is considered an antipatant.

However, since you are not implementing a web interface and you are not dealing with a highly threaded environment, I would say that there is a way to go. It is not that you are going through the institutions. Your biggest fear is the N + 1 call for the database through a compilation, but it is a cron job, because the performance may be is not a big issue than code cleanliness. If you are really worried about it, make sure that you can get all your collections by calling a DAO, which can be selected *.

In addition, you were effectively looking into an open session already when you were doing everything in the same transaction. In spring, the sessions are opened on the basis of transactions per transaction, so keeping a transaction open for a long time is effectively similar to opening a session for long periods of time. The only real difference in your case will be the fact that you may be able to avoid the lazy initialization error on the road from time to time.

edit

It is being said that it takes some time to establish an open session in view So, unless you have a specific problem to do everything in the same transaction, you can go back to it.

In addition, I noticed that you mentioned opening a transaction in the batch layer and opening the "mini transaction" in the service layer. This is not the most obviously a good idea. In the annotation-driven transaction session of Spring, there will be a pagerac on any current open transaction. This means that such transactions that are read-only, suddenly have to read and write suddenly if the current transaction is read-written. Also, the session will not be flushed until the external transaction is completely exhausted, so there is no point in marking the service level with the @transaction .

I really like sometime ago. Insert @transaction on multiple layers.

Comments