0

i have a question about annotation My Class:

@Override
@Transactional
public void process() {
  . . .
   send(persons);
}

public void send(List<person> persons) {
  . . .
   // person list size 1.000.0000
  for(...){
   update(persons); --> 1000, 1000 sending for loop
  }
}

public void update(List<person> persons){
   ...
   List<person> errorPersons;
   ...
   persons.forEach(person-> {
     person.setName("Google - " + person.getName());         
   });

   persons.removeAll(errorPersons);

   getSession().getTransaction().commit(); //--|
   getSession().beginTransaction();        //--| > is works!
   getSession().clear();                   //--|

   send(persons); //recursive

} 

It works as follows. How can I do this with annotation?

   getSession().getTransaction().commit(); //--|
   getSession().beginTransaction();        //--| > is works!
   getSession().clear();  

I tried a few methods but it didn't work, can you help with this issue?

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void update(List<person> persons){
   getSession().getTransaction().commit(); //--> Not Working
}

@Transactional(propagation = Propagation.REQUIRES)
public void update(List<person> persons){
   getSession().getTransaction().commit(); //--> Not Working
}

I just want to do, how can I do this more optimized?

netdevnet
  • 49
  • 1
  • 5

2 Answers2

0

One way of optimizing this could be to use ScrollableResult to get the list of person and iterate over the ScrollableResult with something like

   ScrollableResults persons = query.scroll(ScrollMode.FORWARD_ONLY);

   while (persons.next()) {
       Person person = (Person) persons.get(0);

       // do the stuff you want to do with a person

       ++numberOfFormsHandled;
       if (numberOfPersonsHandled % 20 == 0) {
          flushAndClearSession();
       }
   }

   if (persons != null) {
       persons.close();
   }

Please let me know if this is usefull.

-Kaj :)

Kaj Hejer
  • 955
  • 4
  • 18
0

Are you using Spring ?

@Transactional annotation generates a proxy around your class/methods to handle the transactions. This proxy can only intercept when the method is called by a client which uses the injected proxy of your class. When you call a method updatefrom within the same class you don't go via the proxy so you don't have transaction management.

@Transactional(propagation = Propagation.REQUIRES_NEW) halts the current transaction (if any), creates a new one and all code within the method is managed by this transaction. Once the method ends in a normal way (no exceptions) the transaction is committed and terminated. after the call the outer transaction is again in control.

See Spring @Transaction method call by the method within the same class, does not work?

Normally when using @Transactional annotations you don't call getSession().getTransaction().commit() It's done for you.

Conffusion
  • 4,335
  • 2
  • 16
  • 28