-
Notifications
You must be signed in to change notification settings - Fork 43
Is read only mode supported? #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm able to get "ORA-01456: may not perform insert, delete, update operation inside a READ ONLY transaction" when executing an INSERT with this code: import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.Option;
import io.r2dbc.spi.R2dbcException;
import io.r2dbc.spi.Result;
import io.r2dbc.spi.TransactionDefinition;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Map;
public class ReadOnlyTransaction {
public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory =
ConnectionFactories.get("r2dbc:oracle://test");
Connection connection = Mono.from(connectionFactory.create()).block();
try (
AutoCloseable closeConnection = () ->
Mono.from(connection.close()).block();
AutoCloseable dropTable = () ->
Mono.from(connection.createStatement("DROP TABLE test").execute())
.map(Result::getRowsUpdated)
.flatMap(Mono::from)
.block()) {
Mono.from(connection.createStatement(
"CREATE TABLE test (id NUMBER PRIMARY KEY)")
.execute())
.map(Result::getRowsUpdated)
.flatMap(Mono::from)
.block();
// Oracle Database has a known limitation in that table must exist for
// at least 1 second before it can be involved in a READ ONLY transaction.
// If this two-second sleep is not here, the result will be:
// "ORA-01466: unable to read data - table definition has changed"
Thread.sleep(2_000);
Mono.from(connection.createStatement("INSERT INTO test VALUES(?)")
.bind(0, 1)
.execute())
.map(Result::getRowsUpdated)
.flatMap(Mono::from)
.block();
class TransactionDefinitionImpl implements TransactionDefinition {
final Map<Option<?>, ?> attributes;
TransactionDefinitionImpl(Map<Option<?>, ?> attributes) {
this.attributes = attributes;
}
@Override
public <T> T getAttribute(Option<T> option) {
@SuppressWarnings("unchecked")
T attribute = (T)attributes.get(option);
return attribute;
}
}
TransactionDefinition transactionDefinition =
new TransactionDefinitionImpl(
Map.of(TransactionDefinition.READ_ONLY, true));
Mono.from(connection.beginTransaction(transactionDefinition))
.block();
Mono.from(connection.createStatement("SELECT id FROM test")
.execute())
.map(result -> result.map(row -> row.get(0)))
.flatMapMany(Flux::from)
.toStream()
.forEach(id -> System.out.println("Queried ID: " + id));
try {
Mono.from(connection.createStatement("INSERT INTO test VALUES(?)")
.bind(0, 2)
.execute())
.map(Result::getRowsUpdated)
.flatMap(Mono::from)
.block();
}
catch (R2dbcException r2dbcException) {
// Expect:
// ORA-01456: may not perform insert, delete, update operation inside a READ ONLY transaction
System.out.println(r2dbcException.getMessage());
}
}
}
} Can you try this out with your DB? Note that this code will DROP a table named "test", so you may want to change the table name if you don't want that to happen. |
ah sorry I was just missing this: @Bean(name = "OracleTransactionManager")
public R2dbcTransactionManager transactionManager(@Qualifier("OracleConnectionPool") ConnectionPool connectionPool) {
return new R2dbcTransactionManager(connectionPool);
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello I am writing code using this library to run arbitrary SQL queries via a service account. I would like to build a connection in read only mode. I have tried the following ways and failed.
First attempt:
Second attempt:
Third attempt:
None of these block attempts to run insert statements.
Is it even possible?
The text was updated successfully, but these errors were encountered: