我们在应用程序中使用spring poller从mySQL DB轮询数据并发送给第三方。 功能就是这样,但是当我们移动到PRODUCTION,因为我们有多个appservers,所有服务器上的作业都在运行,我们需要在所有服务器上运行它来处理请求。
轮询时间配置为每5秒运行一次。
但即使我们添加了更新语句,也会在多个服务器中拾取特定记录,因为两个服务器同时运行。
我们有以下配置
<int-jdbc:inbound-channel-adapter id="datachannel"
query="${sql}"
data-source="dbDataSource" max-rows-per-poll="1" row-mapper="pollerdatamapper"
update="update <table> set flag=1 where id =:Id">
<int:poller fixed-rate="${pollerinterval}">
<int:transactional/>
</int:poller>
</int-jdbc:inbound-channel-adapter>
对于来自上述轮询器
的每条记录,将调用PollerService类,如下所示<int:service-activator input-channel="datachannel"
output-channel="executerchannel" ref="pollerservice" method="getRecordFromPoller">
</int:service-activator>
公共类PollerService {
private static final Logger LOGGER = Logger.getLogger(PollerService.class);
public PollerDataBO getRecordFromPoller(PollerDataBO pollerDataBO)
{
LOGGER.info("call for the Id " + Id);
}
您能否确认是否有任何交易设置我们可以限制在其他服务器中选择相同的记录。
答案 0 :(得分:0)
是的,SELECT ... FOR UPDATE
应该是很好的解决方案:
https://docs.oracle.com/cd/E17952_01/mysql-5.1-en/innodb-locking-reads.html
您也可以尝试使用isolation="SERIALIZABLE"
<int:transactional/>
,但我对它没有太多信心。
此外,我认为我们可以改进代码中的JdbcPollingChannelAdapter
,如:
if (this.updatePerRow) {
for (Object row : payload) {
executeUpdateQuery(row);
}
}
跳过那些未更新的行。
随意就此问题提出JIRA。