Skip to content
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

fix: EXPOSED-242 [PostgreSQL] Cannot change connection setting in middle of a transaction #1949

Merged
merged 3 commits into from
Dec 20, 2023

Conversation

bog-walk
Copy link
Member

The lazy property initializer of a new database connection attempts to reset parameters (like transaction isolation level and read only mode), regardless of whether connections are being reused from a connection pool instance.
This can be observed, for example, when schema settings are placed in HikariConfig, which opens a database transaction leading to thrown exceptions when Exposed later attempts to reset parameters:

org.postgresql.util.PSQLException: Cannot change transaction read-only property in the middle of a transaction.

This PR builds on the changes introduced in PR #1943 by also retrieving and caching the readOnly mode set by the DataSourceand avoiding redundant resets.

Note: To ensure that these resets are avoided and that the DataSource is the single source of truth, duplicate settings should not be placed in DatabaseConfig (otherwise Exposed will treat these as overrides, as it already does for per-transaction parameter settings).

…ansaction

Exposed attempts to reset connection settings (isolation level and read only) every
time a new transaction is created, if the transaction settings don't match the
default settings. This is regardless of whether a connection pool is being used
with its own connection settings.

The first half of this issue has already been fixed (PR 1943) so the next exception
thrown becomes: "Cannot change transaction read only in the middle of a transaction."

The same cache and check implementation for that fix has now been applied to the
read only setting when a new transaction is created.
…dle of a tansaction

Move tests to PostgreSQL package.
…dle of a transaction

Adjust Spring connection spy tests as readOnly no longer set on every connection.
assertTrue(con1.verifyCallOrder("setReadOnly", "setAutoCommit", "commit", "close"))
assertTrue(con1.verifyCallOrder("setAutoCommit", "commit", "close"))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Spring tests use a DataSourceSpy to mock connections and save calls to setReadOnly() as part of transaction connection calls.

The test output has changed since readOnly is no longer unnecessarily set on every connection, since its value never changes.

@bog-walk bog-walk merged commit 948e5d5 into main Dec 20, 2023
3 checks passed
@bog-walk bog-walk deleted the bog-walk/fix-readonly-hikari branch December 20, 2023 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IsAutoCommit = false & transactionIsolation = "Transaction_Serializable" result in a PSQLException
2 participants