2016-04-05 7 views
2

Ich richte gerade mein Kamel-Projekt ein und ich kann meinen JPA-Poller nicht auf mehreren gleichzeitigen Servern arbeiten lassen. HierWie Kamel JPA-Komponente in der gleichen Datenbank mit mehreren Servern verwenden?

ist mein Kamel Route:

public class TicketPoller extends RouteBuilder { 

    /** The uri. */ 
    private final String uri = "jpa://Ticket?consumeDelete=false&consumeLockEntity=true&consumer.SkipLockedEntity=true&consumer.query=select t from Ticket t where t.state=1"; 

    @Override 
    public void configure() { 
     from(uri).to("log:input"); 

    } 
} 

Ich benutze @Consumed Annotation den Ticket-Status zu ändern, wenn abgefragt direkt in meine Hibernate Einheit:

@Entity 
@Table(name = "TICKET", schema = "TEIKITEL") 
public class Ticket implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "TICKET_ID") 
    private String ticketId; 

    @Column(name = "STATE") 
    private int state; 

    ... 

    @Consumed 
    public void changeTicketState() { 
     this.state = 2; 
    } 

    @Override 
    public String toString() { 
     return "[email protected]=" + this.ticketId; 
    } 
} 

Es funktioniert gut, wenn ich es starten auf einem einzigen Tomcat-Server (Tomcat 8) von Eclipse.

Aber wenn ich 2 Server Polling auf der gleichen Datenbank starten habe ich diese Fehler, wenn ich ein paar Zeilen in meinem TICKET-Tabelle einfügen:

Auf meinem ersten Server ich das sehen kann:

Hibernate: select TICKET_ID from TEIKITEL.TICKET where TICKET_ID =? for update nowait 
2016-04-05 15:04:56,796 INFO [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] input(180) - Exchange[ExchangePattern: InOnly, BodyType: com.teikitel.model.entity.Ticket, Body: [email protected]=TICKET1] 
Hibernate: select TICKET_ID from TEIKITEL.TICKET where TICKET_ID =? for update nowait 
2016-04-05 15:04:56,812 INFO [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] input(180) - Exchange[ExchangePattern: InOnly, BodyType: com.teikitel.model.entity.Ticket, Body: [email protected]=TICKET2] 

On mein zweiter Server:

Hibernate: select TICKET_ID from TEIKITEL.TICKET where TICKET_ID =? for update nowait 
2016-04-05 15:04:56,859 WARN [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] o.h.e.j.spi.SqlExceptionHelper(144) - SQL Error: 54, SQLState: 61000 
2016-04-05 15:04:56,859 ERROR [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] o.h.e.j.spi.SqlExceptionHelper(146) - ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired 
Hibernate: select TICKET_ID from TEIKITEL.TICKET where TICKET_ID =? for update nowait 
2016-04-05 15:04:56,874 WARN [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] o.h.e.j.spi.SqlExceptionHelper(144) - SQL Error: 54, SQLState: 61000 
2016-04-05 15:04:56,874 ERROR [Camel (camel-1) thread #0 - jpa://com.teikitel.model.entity.Ticket] o.h.e.j.spi.SqlExceptionHelper(146) - ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired 

Hat jemand in das gleiche Problem laufen?

Loic

Antwort

2

Es gibt keine Fehler!

Diese Fehlerprotokolle stammen von Hibernate, nicht von Camel.

Camel erledigt seinen Job und überspringt das in der Datenbank gesperrte Element (Ihre ausgelöste Protokollaktion wird nur einmal für eine Instanz ausgeführt), aber es verwendet Hibernate, um seine blockierungsfreie Auswahlanforderung auszuführen. Hibernate wirft eine Ausnahme, die erfolgreich von Camel ABER ignoriert wird, den Fehler in Ihrer Protokollausgabe zu drucken. Das siehst du.

I gess die Lösung für Ihr Problem ist, das Hibernate-Protokoll auf eine höhere Ebene zu setzen.

mit Problemen wie Thesen (Synchro) zögern Sie nicht, die Verzögerungsverfahren in Kamel zu verwenden, um besser zu verstehen:

public class TicketPoller extends RouteBuilder { 

/** The uri. */ 
private final String uri = "jpa://Ticket?consumeDelete=false&consumeLockEntity=true&consumer.SkipLockedEntity=true&consumer.query=select t from Ticket t where t.state=1"; 

@Override 
public void configure() { 
    from(uri).delay(10000).to("log:input"); //wait 10sec 

} 

}

0

es scheint, wie das Unternehmen bereits für den anderen Thread ausgeführt wird in dem ersten Server gesperrt ist. Sie sperren die Zelle mit consumeLockEntity = true und Sie warten nicht auf die Version consumer.SkipLockedEntity = true, so dass die Verbindung im zweiten Server nach dem Versuch ohne warten geschlossen ist.