I'm creating a resource subscription using transaction 1, before this transaction 1 returns , it adds the request , response and jpa query fetched just created subscription resource into a queue which is taken care by by executor service threads.
This executorService starts separate transaction 2, a uses to jpa query to read a specific attribute of subscription resource ,but it gets null value , but the previous transaction 1 found it(coz may be it itself created it). Transaction 2 need to read the current value but not founding it.
I'm using Ecliplink 2.6, JDK 1.8 and Wildfly 10.Final.
I have looked into whether eclipselink have persisted it to DB or kept in persistenceContext coz, transaction is still not complete and new transaction trying to read it.
That's normal transaction behavior.
As long as T1 is not commited T2 cannot see the data from T1.
Related
The below is my requirement:
1. An MDB receives a message
Triggers a asynchronous method in another session bean - asynchronous because this method will be a long running thread and we don't want to hold the MDB thread for long time. The asynchronous method read's records from DB, processes them and calls #3.
Writes to another MQ and then inserts some data into DB. POSTING TO MQ and DB INSERT should be in one transaction.
Here is the implementation :
For #1 - Using an MDB - container managed transaction without any transaction attribute.
For #2 - A stateless session bean - container managed, asynchronous, but transaction attribute as NOT_SUPPORTED (not supported because this is a long running thread, so don't want the transaction to be timed out).
For# 3 - A stateless sessions bean (invoked from #2 for every record that's being read in 2 - executed in a loop) - transaction attribute - REQUIRES_NEW because this method posts to MQ and Inserts into DB.
Issues:
Runtime Exception - When I throw a run time exception from #3, the next records are not processed - the session bean just exits.
Exception - When throwing a custom exception, the message on the queue is not reverted when DB insert fails.
What is the best way to implement or resolve this issue.
I did my best to give details - appreciate any help on this.
I'am adding some record in db using hibernate, but when i try to get the same record in some millis then it is returning 0 results.
This is the flow:
Create a put request.
Put result in db.
Response received 202 accepted.
Then same controller sends the request to another controller which then tries to update that record.
It returns result as failure.
Environment:
JDK 8
Spring boot 1.2.5
Hibernate 4.3.11.Final
I tried following ways:
Set session flush mode to ALWAYS and COMMIT.
Manually did session.flush() and session.clear()
Please provide the solution as soon as possible.
Following is a hypothetical situation on Spring 3.x and Hibernate3.x
I have a service layer in spring which invokes 3 DAOs to construct a model.
The DAOs are transactional(#Transactional) and have lazy loaded hibernate collections.
The service method causes a few updates ,along with the fetch of data.
A typical DAO method will be as follows -
public O create(I entity) throws GenericException {
getOrCreateSession().save(entity);
return (O)entity;
}
I have the following questions around OSIV -
1.How many times is this session flushed(database update) in the default AUTO mode?
2.Can OSIV be made to extend the session beyond a single request (to a conversation)?
The AUTO flush mode will execute the pending DML statements when:
the current transaction is committed
when a query might target an entity table, that's current enqueued for flushing
Spring Webflow has support for long conversations.
What i do
I have a async system which react whenever a new entity is created in main system and this async system query the database for the newly created entities.
How i do it
For creating the msgs for async system i use hibernate interceptor.
So whenever a new entity is created the onSave method of the interceptor is called and i
save the entity id in a list, and now when afterTransactionComplete(Transaction tx) is
called , i flush all the entity id in the list to async system using a messaging system(ActiveMq).
What is the problem
Now the problem arises when there are more then one transaction are in process.. and both
transactions creates entities.
Let me take a example:
Tx_A create entity EA1, EA2.
Tx_B creates entity EB1, EB2.
Now let say execution flow happens this way:
[1] onSave for EA1, i add EA1 id to flushList
[2] onSave for EB1, i add EB1 id to flushList
[3] afterTransactionComplete(tx) for Tx_A
Now at this point i will flush EA1 and EB1 id to async system which when query database
for EB1 found null as transaction Tx_B is still not completed.
Now this issue can be solve if in onsave call i can get the transaction id and then in afterTransactionCompletion i can flush only entity related to that transaction
[1] Now Is there a way to get this transaction id ?
[2] Is there some other solution for the above problem ?
i am using hibernate 4.2.2
the problem will arise only if we are using global scope interceptor.
If we use session scope interceptor then there is no problem as for each new transaction there is a new interceptor.
I want to perform client request in order they called session bean. But sometimes second request executed successfully before first one.
Is sequential client request execution is possible using ejb2 stateless session Bean ?
public generate(){
.................
update()
.............
}
private update(){
debugLog(" update query for "+id);
//code for update query
debugLog(" execute update query for "+id);
}
When I send two request simultaneously i got log like ..
update query for 16
update query for 16
execute update query for 17
execute update query for 16
But i want to execute it serially like
update query for 16
update query for 16
execute update query for 16
execute update query for 17
EJB-3.x Specific :
You need singleton bean - #Singleton, here you are using stateless bean which might execute parallely & independently for requests in random order.
Now sequencing the events in order, you have to use locking mechanism at class/method level based on your requirements.
By default, beans annoted with #Singleton are container managed & uses locking mode LockType.WRITE, explicitly can apply #ConcurrencyManagement(CONTAINER). If any of the method is being called by a client, all the other requests will have to wait for the previous call to return.
You can also annotate at method level with #Lock(LockType.WRITE). Therefore, the sequence of the call will pertain the order in which they are called by clients.
EJB-2.x Specific :
You have to create singleton on your own as annotation aren't available.
Not sure about container managed concurrency in EJB-2.x, but synchronizing the entry method would definitely help, as it is calling other methods internally.
Edit : Delegate the requests from the beans to a singleton utility class & synchronize method appropriately. Therefore it will resolve both, the pooling & sychronizing issue with stateless beans.