JDBC:inbound-channel-adapter max-row如何与select for update一起使用?

时间:2019-08-26 03:53:45

标签: oracle spring-integration spring-jdbc

我正在使用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  ;

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

1 个答案:

答案 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;

因此,这是受限制的地方。我认为,即使ROWNUMFOR UPDATE不能一起使用,到目前为止您的情况还是可以保证的。