apache / apache/incubator-seata

oracle下使用seata,oracle驱动为ojdbc8:21以上时,使用java.sql.PreparedStatement#addBatch方法会报错

Open
#4,570 1 comment 0 reactions 0 assignees View on GitHub
task: help-wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.