有没有办法克服 DSRA9010E“WebSphere 不支持 'setReadOnly'”异常?
Is there a way to overcome DSRA9010E "'setReadOnly' is not supported on the WebSphere" exception?
我们的应用程序正在使用 Spring 进行交易管理,并将某些交易标记为只读。在使用 Oracle JDBC 连接在 websphere (8.5.5.3) 上部署我们的应用程序时,我们遇到如下异常:
Caused by: java.sql.SQLException: DSRA9010E: 'setReadOnly' is not supported on the WebSphere java.sql.Connection implementation.
at com.ibm.ws.rsadapter.spi.InternalOracleDataStoreHelper.setReadOnly(InternalOracleDataStoreHelper.java:371)
at com.ibm.ws.rsadapter.jdbc.WSJdbcConnection.setReadOnly(WSJdbcConnection.java:3646)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.getTargetConnection(LazyConnectionDataSourceProxy.java:410)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376)
at com.sun.proxy.$Proxy476.getMetaData(Unknown Source)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:619)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:239)
at com.sun.proxy.$Proxy476.getMetaData(Unknown Source)
我知道 websphere 试图告诉我什么,但我想知道是否有办法禁用此检查,以便忽略 Connection.setReadonly 调用而不是抛出异常。
当然我也可以将应用程序更改为不使用只读事务,但那样会复杂得多。
尝试像这样打开 connection
对象:
Context ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("jdbc/OracleDS");
Connection conn = ds.getConnection();
if (conn.isWrapperFor(oracle.jdbc.OracleConnection.class)) {
// Returns an object that implements the given interface to
// allow access to non-standard methods, or standard methods
// not exposed by the proxy.
oracle.jdbc.OracleConnection oraCon = conn.unwrap(oracle.jdbc.OracleConnection.class);
// Do some Oracle-specific work here.
oraCon.setReadOnly(readOnly);
....
}
conn.close();
见WebSphere Application Server and the JDBC 4.0 Wrapper Pattern
Oracle JDBC(从 12c 开始;也许还有 11g?)与 readonly 一起使用可能会很棘手 -
根据 https://marschall.github.io/2017/01/28/oracle-read-only.html:
Calling Connection.setReadOnly(true) with the 12c driver no longer establishes a read only transaction
这意味着 Spring(版本 4.3.7 之前)也难以使用 Oracle JDBC 设置只读事务(参见之前的 link)。
为了克服这个问题,您需要在 SQL 中手动包含 SET TRANSACTION READ ONLY
,而不是依赖 Spring 的 @Transactional(readOnly=true)
。
但是,从 Spring 4.3.7 开始,事务现在可以正常运行,因此您应该不会再看到此问题 (https://github.com/spring-projects/spring-framework/issues/19774)
我们的应用程序正在使用 Spring 进行交易管理,并将某些交易标记为只读。在使用 Oracle JDBC 连接在 websphere (8.5.5.3) 上部署我们的应用程序时,我们遇到如下异常:
Caused by: java.sql.SQLException: DSRA9010E: 'setReadOnly' is not supported on the WebSphere java.sql.Connection implementation.
at com.ibm.ws.rsadapter.spi.InternalOracleDataStoreHelper.setReadOnly(InternalOracleDataStoreHelper.java:371)
at com.ibm.ws.rsadapter.jdbc.WSJdbcConnection.setReadOnly(WSJdbcConnection.java:3646)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.getTargetConnection(LazyConnectionDataSourceProxy.java:410)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376)
at com.sun.proxy.$Proxy476.getMetaData(Unknown Source)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:619)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:239)
at com.sun.proxy.$Proxy476.getMetaData(Unknown Source)
我知道 websphere 试图告诉我什么,但我想知道是否有办法禁用此检查,以便忽略 Connection.setReadonly 调用而不是抛出异常。
当然我也可以将应用程序更改为不使用只读事务,但那样会复杂得多。
尝试像这样打开 connection
对象:
Context ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("jdbc/OracleDS");
Connection conn = ds.getConnection();
if (conn.isWrapperFor(oracle.jdbc.OracleConnection.class)) {
// Returns an object that implements the given interface to
// allow access to non-standard methods, or standard methods
// not exposed by the proxy.
oracle.jdbc.OracleConnection oraCon = conn.unwrap(oracle.jdbc.OracleConnection.class);
// Do some Oracle-specific work here.
oraCon.setReadOnly(readOnly);
....
}
conn.close();
见WebSphere Application Server and the JDBC 4.0 Wrapper Pattern
Oracle JDBC(从 12c 开始;也许还有 11g?)与 readonly 一起使用可能会很棘手 - 根据 https://marschall.github.io/2017/01/28/oracle-read-only.html:
Calling Connection.setReadOnly(true) with the 12c driver no longer establishes a read only transaction
这意味着 Spring(版本 4.3.7 之前)也难以使用 Oracle JDBC 设置只读事务(参见之前的 link)。
为了克服这个问题,您需要在 SQL 中手动包含 SET TRANSACTION READ ONLY
,而不是依赖 Spring 的 @Transactional(readOnly=true)
。
但是,从 Spring 4.3.7 开始,事务现在可以正常运行,因此您应该不会再看到此问题 (https://github.com/spring-projects/spring-framework/issues/19774)