我目前正在设置我的camel项目,但我不能让我的JPA轮询器在多个并发服务器上工作。
这是我的骆驼路线:
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");
}
}
在我的Hibernate实体中直接轮询时,我使用@Consumed注释来更改票证状态:
@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 "Ticket@ticketId=" + this.ticketId;
}
}
当我在Eclipse的一个Tomcat服务器(Tomcat 8)上启动它时,它工作正常。
但是当我在同一个数据库上启动2个服务器轮询时,当我在TICKET表中插入一些行时出现这些错误:
在我的第一台服务器上,我可以看到:
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: Ticket@ticketId=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: Ticket@ticketId=TICKET2]
在我的第二台服务器上:
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
是否有人遇到同样的问题?
卢瓦克
答案 0 :(得分:3)
没有错误!
这些错误日志来自Hibernate,而不是来自Camel。
Camel执行其Job并跳过锁定在数据库中的元素(触发的日志操作仅在一个实例上执行一次)但它使用Hibernate执行其非阻塞选择请求。 Hibernate抛出一个异常,Camel BUT 成功忽略该异常,在日志输出中打印错误。这就是你所看到的。
我认为你的问题的解决方案是将Hibernate日志设置到更高的级别。
像这些问题(同步)一样,不要犹豫,使用骆驼的延迟方法来更好地理解:
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
}
}
答案 1 :(得分:0)
似乎实体已经为第一台服务器中运行的其他线程锁定了。您正在使用 consumeLockEntity = true 锁定单元格,并且您没有等待发布 consumer.SkipLockedEntity = true ,因此在尝试后无需等待即可关闭第二台服务器中的连接。