我正在使用select for update查询,以避免多个JVM重复处理,并且在max-row=10
中有int-jdbc:inbound-channel-adapter
。
可以说该表有50,000条记录。
spring / integration / jdbc只能锁定10行或50000吗?
也,根据文档:https://docs.spring.io/spring-integration/docs/5.2.0.M3/reference/html/jdbc.html
“建议通过特定于供应商的查询选项使用结果集限制,例如MySQL LIMIT或SQL Server TOP或Oracle的ROWNUM。请参阅特定供应商的文档以获取更多信息。”
这意味着服务器将选择查询提取的所有记录。
<int-jdbc:inbound-channel-adapter
id="initial.poller"
query="select id from transaction where status='created'"
max-rows="10"
update="update transaction set status='processed' where ID in (:id)"
row-mapper="pollerRowMapper"
data-source="dataSource" channel="transactionChannel">
<int:poller fixed-rate="200" time-unit="MILLISECONDS">
<int:transactional />
</int:poller>
</int-jdbc:inbound-channel-adapter>
我在调试模式下检查了jvm仅锁定了10行,而其他JVMS正在拾取并处理其他记录。
1)spring / hibernate如何与oracle通信以仅锁定它正在选择的10条记录?
2)如果必须在查询中使用ROWNUM,max-rows
的用途是什么?
编辑1:我们无法同时选择更新和rownum。在oracle上,这些都不被允许:
select * from (select id from transaction where status='created' order by id) WHERE rownum <= 10 FOR UPDATE SKIP LOCKED ;
select * from (select id from transaction where status='created' order by id FOR UPDATE SKIP LOCKED) WHERE rownum <= 10 ;
如何获得性能优化?表中有数百万或记录。
答案 0 :(得分:0)
查看其JavaDocs:
/**
* The maximum number of rows to query. Default is zero - select all records.
* @param maxRows the max rows to set
* @since 5.1
*/
public void setMaxRows(int maxRows) {
因此,我们可以假设这确实会以某种方式限制记录。这就是在代码中完成的方式:
return new PreparedStatementCreatorWithMaxRows(preparedStatementCreator,
JdbcPollingChannelAdapter.this.maxRows);
...
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement preparedStatement = this.delegate.createPreparedStatement(con);
preparedStatement.setMaxRows(this.maxRows); // We can't mutate provided JdbOperations for this option
return preparedStatement;
}
让我们看一下那些JavaDocs:
/**
* Sets the limit for the maximum number of rows that any
* <code>ResultSet</code> object generated by this <code>Statement</code>
* object can contain to the given number.
* If the limit is exceeded, the excess
* rows are silently dropped.
*
* @param max the new max rows limit; zero means there is no limit
* @exception SQLException if a database access error occurs,
* this method is called on a closed <code>Statement</code>
* or the condition {@code max >= 0} is not satisfied
* @see #getMaxRows
*/
void setMaxRows(int max) throws SQLException;
因此,这是受限制的地方。我认为,即使ROWNUM
与FOR UPDATE
不能一起使用,到目前为止您的情况还是可以保证的。