apache / apache/incubator-seata
oracle下使用seata,oracle驱动为ojdbc8:21以上时,使用java.sql.PreparedStatement#addBatch方法会报错
- Dominant language
- Java
- Stars
- 26k
- Forks
- 8.8k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 4
Description
- [ ] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.
### Ⅰ. Issue Description
代码类似于:
```
@GlobalTransactional
public void test(){
Connection connection = null;
try {
connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO T_TEST(xxx) values (xxx));
preparedStatement.setString(1,"123");
preparedStatement.setString(2,"123");
preparedStatement.addBatch();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
```
在整合ojdbc8:19.xxx版本的时候能正常使用,在整合21版本以上后,会报错,
21.1.0.0报的是“DML Returning cannot be batched”的异常。21.3.0.0以上报的是
```
java.lang.NullPointerException: null
at oracle.jdbc.driver.OraclePreparedStatement.registerReturnParamsForAutoKey(OraclePreparedStatement.java:11206)
at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2009)
at oracle.jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:9823)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.addBatch(OraclePreparedStatementWrapper.java:998)
at com.p6spy.engine.wrapper.PreparedStatementWrapper.addBatch(PreparedStatementWrapper.java:377)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.addBatch(HikariProxyPreparedStatement.java)
at io.seata.rm.datasource.AbstractPreparedStatementProxy.addBatch(AbstractPreparedStatementProxy.java:232)
at com.fingard.frisk.exposure.web.controller.test.TestCotroller.lambda$test4$2(TestCotroller.java:104)
```
### Ⅴ. Anything else we need to know?
原因是seata在执行insert语句时,要拿到主键返回,所以执行的prepareStatement方法改成了
connection.prepareStatement("INSERT INTO T_TEST(xxx) values (xxx),new String[]{URID});
代码位置是:io.seata.rm.datasource.AbstractConnectionProxy#prepareStatement(java.lang.String)
但是21以上执行带主键返回值的addbatch会直接报错。
该问题把ojdbc8降到19.xx能够解决。
但是seata能不能兼容ojdbc8:21.1.0.0以上版本的java.sql.PreparedStatement#addBatch方法
### Ⅵ. Environment:
- JDK version : 1.8
- Seata version: 1.4.2
- OS :
- Others:
Contributor guide
Research direction
Start at io.seata.rm.datasource.AbstractConnectionProxy#prepareStatement and follow the batching path through AbstractPreparedStatementProxy#addBatch. Reproduce the reported insert with ojdbc8 19.x, 21.1.0.0, and 21.3.0.0 or later, then compare the behavior and exceptions. Done means PreparedStatement#addBatch works with the newer driver while preserving Seata's generated-key handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100