2016-11-09 3 views
0

Ich habe zwei Feder Kaninchen Verbraucher A und B.Frühling Kaninchen und JDBC Transaktion Ausgabe

Verbraucher A:

protected void process(Message amqpMessage, Channel channel) 
      throws Exception { 
    Session mysession=sessionRepository.findOne(5); 
    mysession.setMyField("bla"); 
    sessionRepository.save(mysession); 
    ServicesHelper.convertAndSend(<Consumer B token>, mysession.getId()); 

} 

Consumer B:

protected void process(Message amqpMessage, Channel channel) 
      throws Exception { 
    //getting event from message 
    Long sessionId=5; 
    Session mysession=sessionRepository.findOne(sessionId); 
    mysession.setMyField("bla-bla"); 
    //And I get there unpredictable optimistic locking exception. 
    sessionRepository.save(mysession); 


} 

Es ist wie jdbc Transaktion in Verbraucher scheint A wird nach dem Beenden der Listener-Methode übergeben, daher ist eine Überlappung möglich. Meine 'Sitzung' hat eine @Version-Spalte, deshalb habe ich dieses Problem entdeckt. Wie man es vermeidet und ist es ein guter Ansatz, dies zu tun? Ich muss nur eine Sitzung in Consumer A verarbeiten und dann an Consumer B übergeben.

+0

Nur schnell, Sie sagen, dass die Transaktion erst nach dem Beenden der Methode oder nach dem 'save' abgeschlossen wird? Letzteres wäre nur möglich, wenn Sie explizit den Aufrufer von 'process' mit' @ Transactional' annotieren. Ist das der Fall? – MikePatel

+0

Hi, ja, ich habe onMessage-Methoden als @Transactional markiert und der Prozess läuft darin. Das Problem ist, dass ich beim Speichern von Entitäten in A oder 2 zufällig OptimisticException erhalte. Ich habe all diese Logik in eine separate Klasse verschoben, die mit @Transactional gekennzeichnet ist (propagation = Propagation.REQUIRES_NEW). Ist es ein guter Weg? – avalon

+0

Ok, auf jeden Fall wichtige Informationen für die Frage. Ich denke, Sie müssen nur die Transaktionsblöcke aufräumen. Zieh sie aus und versuche es so, wie ich es in der Antwort vorgeschlagen habe und ich denke, es sollte in Ordnung sein. – MikePatel

Antwort

1

Ich denke, Sie sprechen möglicherweise über spring-data hier nicht spring-jdbc. Wenn dies der Fall ist (Entschuldigung, wenn dies nicht der Fall ist) und Sie CrudRepository verwenden, liegt das wahrscheinlich daran, dass Interaktionen mit dem Repository alle @Transactional sind.

Zum Beispiel, hier ist die eigentliche Signatur speichern

@Transactional 
    public <S extends T> S save(S entity) { 

     if (entityInformation.isNew(entity)) { 
      em.persist(entity); 
      return entity; 
     } else { 
      return em.merge(entity); 
     } 
    } 

ich Refactoring die folgende und es erneut versuchen würde vorschlagen: -

protected void process(Message amqpMessage, Channel channel) 
      throws Exception { 

    ServicesHelper.convertAndSend(<Consumer B token>,adaptSession().getId())); 

} 

@Transactional 
protected Session adaptSession(){ 
    Session mysession=sessionRepository.findOne(5); 
    mysession.setMyField("bla"); 
    sessionRepository.save(mysession); 
    return mysession; 
} 

und

@Transactional 
protected void process(Message amqpMessage, Channel channel) 
      throws Exception { 
    //getting event from message 
    Long sessionId=5; 
    Session mysession=sessionRepository.findOne(sessionId); 
    mysession.setMyField("bla-bla"); 
    //And I get there unpredictable optimistic locking exception. 
    sessionRepository.save(mysession); 
} 

Was sollte bringen Sie die Transaktionseinheiten in Übereinstimmung. Versuche das und ich weiß es.

Verwandte Themen