spring-mvc - 从多个应用服务器运行的 Spring Poller
问题描述
我们在我们的应用程序中使用 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>
公共类轮询服务 {
private static final Logger LOGGER = Logger.getLogger(PollerService.class);
public PollerDataBO getRecordFromPoller(PollerDataBO pollerDataBO)
{
LOGGER.info("call for the Id " + Id);
}
您能否确认是否有任何交易设置可以限制我们在其他服务器中选择相同记录。
解决方案
对,SELECT ... FOR UPDATE
对你来说应该是很好的解决方案:
https://docs.oracle.com/cd/E17952_01/mysql-5.1-en/innodb-locking-reads.html
你也可以试试isolation="SERIALIZABLE"
for the <int:transactional/>
,但我对它没有太大的信心。
另外我认为我们可以改进JdbcPollingChannelAdapter
代码中的内容,例如:
if (this.updatePerRow) {
for (Object row : payload) {
executeUpdateQuery(row);
}
}
并跳过那些未更新的行。
随意就此事提出JIRA。
推荐阅读
- eclipse - Spring Tools Suite 4 下载失败,Eclipse Photon
- matlab - 如何反转 3D Barplot Matlab 中的一个轴
- html - 如何使用 CSS 在范围输入中设置最小值和最大值
- python - ^ 不支持的操作数类型:“str”和“int”异或解密
- scala - Scala案例类使用浅拷贝还是深拷贝?
- android - 前 21 个 API 设备上的改造 API 失败 javax.net.ssl.SSLProtocolException:SSL 握手中止:
- io - 输入输出流在 Web 表单功能中不起作用
- javascript - 页面加载前加载栏完成
- amazon-web-services - Boto3雅典娜查询而不将数据保存到s3
- ios - How to display two different images coming from backend in different image views in iOS?