JDBC:入站通道适配器最大行如何与选择更新一起工作?



我正在使用选择进行更新查询以避免多个 JVM 重复处理,我在int-jdbc:inbound-channel-adaptermax-row=10

假设该表有 50,000 条记录。

弹簧/集成/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>

我在调试模式下检查,只有 10 行被 jvm 锁定,其他 JVM 正在拾取和处理其他记录。

1) spring/hibernate 如何与 oracle 通信以仅锁定它正在选择的 10 条记录?

2)如果必须在查询中使用ROWNUM,max-rows的目的是什么?

编辑1:我们无法同时选择更新和行数。这些在预言机上都不允许:

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  ;

如何获得性能优化? 表有数百万条或记录。

参见其 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一起使用,您也可以安全地使用。

最新更新