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
.
一起工作,你目前拥有的东西也是安全的
我正在使用 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
.