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

R2DBC: @Transactional(readOnly) is applied to the connection before the transaction has begun #28610

Closed
hheg opened this issue Jun 11, 2022 · 2 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug
Milestone

Comments

@hheg
Copy link

hheg commented Jun 11, 2022

Affects: <Spring Framework version>
At least 5.3.19->5.3.20


I was trying to set a transaction to read only to fake a read only connection. Turns out that the SET TRANSACTION READ ONLY statement is called before there's any transaction going, rendering it useless.
This happens in

return connectionMono.flatMap(con -> prepareTransactionalConnection(con, definition, transaction)
when you run the R2dbcTransactionManger with enforceReadOnly= true.
The code reads that it tries to prepareTransactionalConnection where the statement is called but then on the next line .then(Mono.from(doBegin(definition, con))) which calls BEGIN is called after the statement has been called so there's no transaction to set to READ ONLY. This results in the following output in postgres 13.3:

[35] LOG:  statement: SET TRANSACTION READ ONLY
[35] WARNING:  SET TRANSACTION can only be used in transaction blocks
[35] LOG:  statement: BEGIN
[35] LOG:  execute S_0/B_1: INSERT INTO <redacted>
[35] DETAIL:  parameters: $1 = <redacted>
[35] LOG:  statement: COMMIT

The method called is set with @Transactional(readOnly=true)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 11, 2022
@jhoeller jhoeller changed the title @Transactional(readOnly) is applied to the connection before the transaction has begun R2DBC: @Transactional(readOnly) is applied to the connection before the transaction has begun Jun 11, 2022
@jhoeller jhoeller added in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug labels Jun 11, 2022
@jhoeller jhoeller added this to the 5.3.21 milestone Jun 11, 2022
@jhoeller jhoeller self-assigned this Jun 11, 2022
@jhoeller
Copy link
Contributor

@mp911de I suppose we simply need to invert the order of those operations: doBegin first, prepareTransactionalConnection right afterwards?

@jhoeller jhoeller removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 11, 2022
@mp911de
Copy link
Member

mp911de commented Jun 13, 2022

prepareTransactionalConnection handles isolation level and auto-commit updates to the connection. Switching the order of operations would break the usage pattern. I suggest moving the SET TRANSACTION READ ONLY call into a method called after Connection.beginTransaction(). Then we would fully align with JDBC.

@snicoll snicoll modified the milestones: 5.3.21, 5.3.x Jun 15, 2022
@jhoeller jhoeller modified the milestones: 5.3.x, 5.3.22 Jul 13, 2022
jhoeller added a commit that referenced this issue Jul 13, 2022
Includes prepareTransactionalConnection variant aligned with JDBC DataSourceTransactionManager.

Closes gh-28610
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants