I am using Java EE, not Spring, in a Payara environment.
I have a job which goes through a list of objects called "position". For each position, a complex algorithm is run, which makes several calculations and changes some objects.
This job with the for-loop is either started by the user clicking a button or by a bean, which starts the job at a certain time.
Something like this:
public void processPositions(){
for(Position position : shortPositions){
try{
for(Trade trade : borrowTrades){
for(TradeEvent event : futureEvents){
cancelEvent(event);
} // end for event
closeTrade(trade);
} // end for trade
}catch(){
// handle exception here
}
} // end for position
}
My problem is now, that, if a problem occurs when one position is processed, Hibernate rolls back the transaction, which is ok.
However, when the next position is taken, the run stops with the exception javax.ejb.EJBTransactionRolledbackException: Client's transaction aborted
.
In principle, I would like to handle the changes for each position (and other corresponding objects) as a single transaction / session, which is independent from the others.
How can I achieve this?
I am a newbie to Hibernate. Without Hibernate, I would open a new transaction when I take the next position object in the loop. I would update/insert/delete the corresponding objects which are related to my position object by the use of SQL and in the end, I would commit everything or rollback. Then I would open a new transaction when taking the next object. However Hibernate is hiding this from the user. I believe that the call for processPositions is done within a session having a transaction. And if this transaction is rollbacked, it is used up. My question is how can I start a new transaction and make all the EntityManagers in the repositories use this new transaction when a persistent object is updated.
I am using Java EE, not Spring, in a Payara environment.
I have a job which goes through a list of objects called "position". For each position, a complex algorithm is run, which makes several calculations and changes some objects.
This job with the for-loop is either started by the user clicking a button or by a bean, which starts the job at a certain time.
Something like this:
public void processPositions(){
for(Position position : shortPositions){
try{
for(Trade trade : borrowTrades){
for(TradeEvent event : futureEvents){
cancelEvent(event);
} // end for event
closeTrade(trade);
} // end for trade
}catch(){
// handle exception here
}
} // end for position
}
My problem is now, that, if a problem occurs when one position is processed, Hibernate rolls back the transaction, which is ok.
However, when the next position is taken, the run stops with the exception javax.ejb.EJBTransactionRolledbackException: Client's transaction aborted
.
In principle, I would like to handle the changes for each position (and other corresponding objects) as a single transaction / session, which is independent from the others.
How can I achieve this?
I am a newbie to Hibernate. Without Hibernate, I would open a new transaction when I take the next position object in the loop. I would update/insert/delete the corresponding objects which are related to my position object by the use of SQL and in the end, I would commit everything or rollback. Then I would open a new transaction when taking the next object. However Hibernate is hiding this from the user. I believe that the call for processPositions is done within a session having a transaction. And if this transaction is rollbacked, it is used up. My question is how can I start a new transaction and make all the EntityManagers in the repositories use this new transaction when a persistent object is updated.
Share Improve this question edited Mar 3 at 14:38 DocU asked Feb 28 at 7:22 DocUDocU 313 bronze badges 2- The word process has a specific meaning in computing. Your use of that term here has a different meaning. I suggest you rewrite to avoid that. – Basil Bourque Commented Feb 28 at 7:43
- You did not explain how the code shown relates to Hibernate nor to a EJB transaction. A minimal reproducible example would improve this Question. – Basil Bourque Commented Feb 28 at 7:46
2 Answers
Reset to default 0You could flush each item of your list. Otherwise you will have go over the transaction manager and initiate a transaction for each item. Then flush it, close the transaction and start all over again.
What you need, is to to tell Java EE to use a new transaction for your methods. The easiest way is to have a method with @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
:
@Stateless
public class ControlService {
@EJB
private TradeService tradeService;
public void processPositions() {
for(Position position : shortPositions) {
tradeService.processPosition(position);
}
}
}
@Stateless
public class TradeService {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public String processPosition(Position position) {
// ... here is your business logic
}
}
The first method, ControlService.processPositions()
runs in the first transaction and each TradeService.processPosition()
will have its own one.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745136370a4613219.html
评论列表(0条)