diff --git a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsink.md b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsink.md index eaf9e5535..1eee31287 100644 --- a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsink.md +++ b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsink.md @@ -42,7 +42,7 @@ Can be found in the instance overview page. **Password:** Password to use to connect to the specified database. -**Transaction Isolation Level:** Transaction isolation level for queries run by this sink. +**Transaction Isolation Level:** Transaction isolation level for queries run by this sink. **Connection Timeout:** The timeout value (in seconds) used for socket connect operations. If connecting to the server takes longer than this value, the connection is broken. A value of 0 means that it is disabled. diff --git a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsource.md b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsource.md index 52a5945e7..11a863f4f 100644 --- a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsource.md +++ b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-batchsource.md @@ -52,6 +52,14 @@ For example, 'SELECT MIN(id),MAX(id) FROM table'. Not required if numSplits is s **Password:** Password to use to connect to the specified database. +**Transaction Isolation Level:** The transaction isolation level of the database connection. +- TRANSACTION_READ_COMMITTED: No dirty reads. Non-repeatable reads and phantom reads are possible. +- TRANSACTION_SERIALIZABLE: No dirty reads. Non-repeatable and phantom reads are prevented. +- TRANSACTION_REPEATABLE_READ: No dirty reads. Prevents non-repeatable reads, but phantom reads are still possible. +- TRANSACTION_READ_UNCOMMITTED: Allows dirty reads (reading uncommitted changes from other transactions). Non-repeatable reads and phantom reads are possible. + +For more details on the Transaction Isolation Levels supported in CloudSQL MySQL, refer to the [CloudSQL MySQL documentation](https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html) + **Connection Arguments:** A list of arbitrary string key/value pairs as connection arguments. These arguments will be passed to the JDBC driver as connection arguments for JDBC drivers that may need additional configurations. diff --git a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-connector.md b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-connector.md index 3197760e0..9cd5d582a 100644 --- a/cloudsql-mysql-plugin/docs/CloudSQLMySQL-connector.md +++ b/cloudsql-mysql-plugin/docs/CloudSQLMySQL-connector.md @@ -27,6 +27,14 @@ authentication. Optional for databases that do not require authentication. **Password:** Password to use to connect to the specified database. +**Transaction Isolation Level:** The transaction isolation level of the database connection. +- TRANSACTION_READ_COMMITTED: No dirty reads. Non-repeatable reads and phantom reads are possible. +- TRANSACTION_SERIALIZABLE: No dirty reads. Non-repeatable and phantom reads are prevented. +- TRANSACTION_REPEATABLE_READ: No dirty reads. Prevents non-repeatable reads, but phantom reads are still possible. +- TRANSACTION_READ_UNCOMMITTED: Allows dirty reads (reading uncommitted changes from other transactions). Non-repeatable reads and phantom reads are possible. + +For more details on the Transaction Isolation Levels supported in CloudSQL MySQL, refer to the [CloudSQL MySQL documentation](https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html) + **Connection Arguments:** A list of arbitrary string tag/value pairs as connection arguments. These arguments will be passed to the JDBC driver, as connection arguments, for JDBC drivers that may need additional configurations. This is a semicolon-separated list of key-value pairs, where each pair is separated by a equals '=' and specifies diff --git a/cloudsql-mysql-plugin/src/main/java/io/cdap/plugin/cloudsql/mysql/CloudSQLMySQLSource.java b/cloudsql-mysql-plugin/src/main/java/io/cdap/plugin/cloudsql/mysql/CloudSQLMySQLSource.java index 80358ce4b..43c63aa9e 100644 --- a/cloudsql-mysql-plugin/src/main/java/io/cdap/plugin/cloudsql/mysql/CloudSQLMySQLSource.java +++ b/cloudsql-mysql-plugin/src/main/java/io/cdap/plugin/cloudsql/mysql/CloudSQLMySQLSource.java @@ -156,6 +156,13 @@ public static class CloudSQLMySQLSourceConfig extends AbstractDBSpecificSourceCo @Description("The existing connection to use.") private CloudSQLMySQLConnectorConfig connection; + @Name(TRANSACTION_ISOLATION_LEVEL) + @Description("Transaction isolation level for queries run by this source.") + @Nullable + private String transactionIsolationLevel; + + private static final String DEFAULT_TRANSACTION_ISOLATION_LEVEL = "TRANSACTION_REPEATABLE_READ"; + @Override protected Map getDBSpecificArguments() { if (getFetchSize() == null || getFetchSize() <= 0) { @@ -168,6 +175,11 @@ protected Map getDBSpecificArguments() { return arguments; } + @Override + public String getTransactionIsolationLevel() { + return transactionIsolationLevel != null ? transactionIsolationLevel : DEFAULT_TRANSACTION_ISOLATION_LEVEL; + } + @Override public void validate(FailureCollector collector) { ConfigUtil.validateConnection(this, useConnection, connection, collector); diff --git a/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-batchsource.json b/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-batchsource.json index a90154670..20c6d872f 100644 --- a/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-batchsource.json +++ b/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-batchsource.json @@ -84,6 +84,20 @@ "label": "Password", "name": "password" }, + { + "widget-type": "select", + "label": "Transaction Isolation Level", + "name": "transactionIsolationLevel", + "widget-attributes": { + "default": "TRANSACTION_REPEATABLE_READ", + "values": [ + "TRANSACTION_REPEATABLE_READ", + "TRANSACTION_READ_UNCOMMITTED", + "TRANSACTION_READ_COMMITTED", + "TRANSACTION_SERIALIZABLE" + ] + } + }, { "widget-type": "keyvalue", "label": "Connection Arguments", diff --git a/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-connector.json b/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-connector.json index 1cebc7850..e641add41 100644 --- a/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-connector.json +++ b/cloudsql-mysql-plugin/widgets/CloudSQLMySQL-connector.json @@ -54,6 +54,20 @@ "widget-attributes": { "default": "3306" } + }, + { + "widget-type": "select", + "label": "Transaction Isolation Level", + "name": "transactionIsolationLevel", + "widget-attributes": { + "default": "TRANSACTION_REPEATABLE_READ", + "values": [ + "TRANSACTION_REPEATABLE_READ", + "TRANSACTION_READ_UNCOMMITTED", + "TRANSACTION_READ_COMMITTED", + "TRANSACTION_SERIALIZABLE" + ] + } } ] }, diff --git a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsink.md b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsink.md index 338a67c9e..5a70a7f30 100644 --- a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsink.md +++ b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsink.md @@ -42,7 +42,7 @@ Can be found in the instance overview page. **Password:** Password to use to connect to the specified database. -**Transaction Isolation Level:** Transaction isolation level for queries run by this sink. +**Transaction Isolation Level:** Transaction isolation level for queries run by this sink. **Connection Arguments:** A list of arbitrary string key/value pairs as connection arguments. These arguments will be passed to the JDBC driver as connection arguments for JDBC drivers that may need additional configurations. diff --git a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsource.md b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsource.md index 8d9ad7171..c477f4a23 100644 --- a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsource.md +++ b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-batchsource.md @@ -52,6 +52,14 @@ For example, 'SELECT MIN(id),MAX(id) FROM table'. Not required if numSplits is s **Password:** Password to use to connect to the specified database. +**Transaction Isolation Level:** The transaction isolation level of the database connection. +- TRANSACTION_READ_COMMITTED: No dirty reads. Non-repeatable reads and phantom reads are possible. +- TRANSACTION_SERIALIZABLE: No dirty reads. Non-repeatable and phantom reads are prevented. +- TRANSACTION_REPEATABLE_READ: No dirty reads. Prevents non-repeatable reads, but phantom reads are still possible. +- Note: PostgreSQL does not implement `TRANSACTION_READ_UNCOMMITTED` as a distinct isolation level. Instead, this mode behaves identically to`TRANSACTION_READ_COMMITTED`, which is why it is not exposed as a separate option. + +For more details on the Transaction Isolation Levels supported in CloudSQL PostgreSQL, refer to the [CloudSQL PostgreSQL documentation](https://www.postgresql.org/docs/current/transaction-iso.html) + **Connection Arguments:** A list of arbitrary string key/value pairs as connection arguments. These arguments will be passed to the JDBC driver as connection arguments for JDBC drivers that may need additional configurations. diff --git a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-connector.md b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-connector.md index 0e502fefd..467469c30 100644 --- a/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-connector.md +++ b/cloudsql-postgresql-plugin/docs/CloudSQLPostgreSQL-connector.md @@ -27,6 +27,14 @@ authentication. Optional for databases that do not require authentication. **Password:** Password to use to connect to the specified database. +**Transaction Isolation Level:** The transaction isolation level of the database connection. +- TRANSACTION_READ_COMMITTED: No dirty reads. Non-repeatable reads and phantom reads are possible. +- TRANSACTION_SERIALIZABLE: No dirty reads. Non-repeatable and phantom reads are prevented. +- TRANSACTION_REPEATABLE_READ: No dirty reads. Prevents non-repeatable reads, but phantom reads are still possible. +- Note: PostgreSQL does not implement `TRANSACTION_READ_UNCOMMITTED` as a distinct isolation level. Instead, this mode behaves identically to`TRANSACTION_READ_COMMITTED`, which is why it is not exposed as a separate option. + +For more details on the Transaction Isolation Levels supported in CloudSQL PostgreSQL, refer to the [CloudSQL PostgreSQL documentation](https://www.postgresql.org/docs/current/transaction-iso.html) + **Connection Arguments:** A list of arbitrary string tag/value pairs as connection arguments. These arguments will be passed to the JDBC driver, as connection arguments, for JDBC drivers that may need additional configurations. This is a semicolon-separated list of key-value pairs, where each pair is separated by a equals '=' and specifies diff --git a/cloudsql-postgresql-plugin/src/main/java/io/cdap/plugin/cloudsql/postgres/CloudSQLPostgreSQLSource.java b/cloudsql-postgresql-plugin/src/main/java/io/cdap/plugin/cloudsql/postgres/CloudSQLPostgreSQLSource.java index 7ebc7d809..e07251a56 100644 --- a/cloudsql-postgresql-plugin/src/main/java/io/cdap/plugin/cloudsql/postgres/CloudSQLPostgreSQLSource.java +++ b/cloudsql-postgresql-plugin/src/main/java/io/cdap/plugin/cloudsql/postgres/CloudSQLPostgreSQLSource.java @@ -157,6 +157,13 @@ public static class CloudSQLPostgreSQLSourceConfig extends AbstractDBSpecificSou @Description("The existing connection to use.") private CloudSQLPostgreSQLConnectorConfig connection; + @Name(TRANSACTION_ISOLATION_LEVEL) + @Description("Transaction isolation level for queries run by this source.") + @Nullable + private String transactionIsolationLevel; + + private static final String DEFAULT_TRANSACTION_ISOLATION_LEVEL = "TRANSACTION_READ_COMMITTED"; + @Override protected Map getDBSpecificArguments() { return Collections.emptyMap(); @@ -173,6 +180,11 @@ protected CloudSQLPostgreSQLConnectorConfig getConnection() { return connection; } + @Override + public String getTransactionIsolationLevel() { + return transactionIsolationLevel != null ? transactionIsolationLevel : DEFAULT_TRANSACTION_ISOLATION_LEVEL; + } + @Override public void validate(FailureCollector collector) { ConfigUtil.validateConnection(this, useConnection, connection, collector); diff --git a/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-batchsource.json b/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-batchsource.json index ea449120d..1308b83e0 100644 --- a/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-batchsource.json +++ b/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-batchsource.json @@ -84,6 +84,19 @@ "label": "Password", "name": "password" }, + { + "widget-type": "select", + "label": "Transaction Isolation Level", + "name": "transactionIsolationLevel", + "widget-attributes": { + "default": "TRANSACTION_READ_COMMITTED", + "values": [ + "TRANSACTION_READ_COMMITTED", + "TRANSACTION_REPEATABLE_READ", + "TRANSACTION_SERIALIZABLE" + ] + } + }, { "widget-type": "keyvalue", "label": "Connection Arguments", diff --git a/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-connector.json b/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-connector.json index 36013ac40..6b89ae657 100644 --- a/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-connector.json +++ b/cloudsql-postgresql-plugin/widgets/CloudSQLPostgreSQL-connector.json @@ -54,6 +54,19 @@ "widget-attributes": { "default": "5432" } + }, + { + "widget-type": "select", + "label": "Transaction Isolation Level", + "name": "transactionIsolationLevel", + "widget-attributes": { + "default": "TRANSACTION_READ_COMMITTED", + "values": [ + "TRANSACTION_READ_COMMITTED", + "TRANSACTION_REPEATABLE_READ", + "TRANSACTION_SERIALIZABLE" + ] + } } ] }, diff --git a/database-commons/src/main/java/io/cdap/plugin/db/config/AbstractDBSpecificSourceConfig.java b/database-commons/src/main/java/io/cdap/plugin/db/config/AbstractDBSpecificSourceConfig.java index f15939ab7..73d57d356 100644 --- a/database-commons/src/main/java/io/cdap/plugin/db/config/AbstractDBSpecificSourceConfig.java +++ b/database-commons/src/main/java/io/cdap/plugin/db/config/AbstractDBSpecificSourceConfig.java @@ -49,6 +49,7 @@ public abstract class AbstractDBSpecificSourceConfig extends PluginConfig implem public static final String DATABASE = "database"; public static final String FETCH_SIZE = "fetchSize"; public static final String DEFAULT_FETCH_SIZE = "1000"; + public static final String TRANSACTION_ISOLATION_LEVEL = "transactionIsolationLevel"; @Name(Constants.Reference.REFERENCE_NAME) @Description(Constants.Reference.REFERENCE_NAME_DESCRIPTION)