JDBC:inbound-channel-adapter max-row 如何与 select 配合使用进行更新?

How JDBC:inbound-channel-adapter max-row works with select for update?

我正在使用 select 进行更新查询以避免多个 JVM 重复处理,并且我在 int-jdbc:inbound-channel-adapter 中有 max-row=10

假设 table 有 50,000 条记录。

spring/integration/jdbc 只锁定 10 行还是 50000 行?

另外,根据文档:https://docs.spring.io/spring-integration/docs/5.2.0.M3/reference/html/jdbc.html

"It is recommended to use result set limiting via vendor-specific query options, for example MySQL LIMIT or SQL Server TOP or Oracle’s ROWNUM. See the particular vendor documentation for more information."

这意味着服务器将选择查询获取的所有记录。

    <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 锁定,其他 JVMS 正在获取并处理其他记录。

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

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

编辑 1:我们无法 select 将 update 和 rownum 放在一起。 None 其中的 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  ;

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

查看其 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.

一起工作,你目前拥有的东西也是安全的