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

Spring 4.1 upgrade and Transaction Propagation issue from readOnly to readWrite [SPR-12807] #17404

Closed
spring-issuemaster opened this issue Mar 11, 2015 · 5 comments

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Venkat Srinivasan opened SPR-12807 and commented

Hello All,
I had posted this question on stackoverflow and somone suggesting writing a test program and open a jira ticket . To summarize, I have a service method A with @Transactional marked readOnly calling a service2 method B with @Transactional marked non-readOnly. We have been using spring 3.x for a while and are now migrating to spring 4 and found that now it gives the exception
"Connection is read-only. Queries leading to data modification are not allowed; "
I tested this with Spring 4.0.9 and it seems to work fine but not 4.1 and above. I was under the assumption a propagation change from readOnly to readWrite in an underlying tx advice if so specified would switch the transaction to write mode. Maybe my understanding is incorrect but this flow seems to work until 4.1. I have attached a test program which illustrates this.
mvn test will fail if the pom.xml in the test package contains spring .version = 4.1.5.RELEASE but work pass through if spring.version = 4.0.9.RELEASE.
We will go back and refactor our code but just curious if in case this is a bug or expected behavior which has been eventually resolved in 4.1.


Thanks in advance


Affects: 4.1 GA, 4.1.4, 4.1.5

Reference URL: http://stackoverflow.com/questions/28978948/spring-4-1-upgrade-causing-transaction-propagation-issue

Attachments:

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Juergen Hoeller commented

What's the stacktrace for that exception? This probably comes out of your JDBC driver? Are you possibly using Hibernate there, in which case you might be affected by #13599 (which finally applies the read-only flag to a Hibernate-managed JDBC Connection)?

This fundamentally works as designed, since this was never designed to upgrade a read-only status to read-write on the fly. The exact behavior depends on the underlying drivers and dialects, so in some scenarios, you may indeed experience this as a regression.

If it is indeed Hibernate in your scenario, you could specify a custom HibernateJpaDialect and set the "prepareConnection" flag to "false".

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Venkat Srinivasan commented

Thanks Juergen. Yes we do indeed use hibernate 4. The stacktrace does come from the jdbc driver

Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2360)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)

I will look through #13599 and see if it indeed is the case. Just curious, will this effect, OpenSessioninViewFilter or that also just manages just the flush mode and not the underlying connection per se.?


Thanks for the help

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Venkat Srinivasan commented

I wrote a custom HibernateJpaDialect with prepareConnection as false and the error indeed does go away. So I guess we are hitting the #13599 issue. Thanks. !
We will rework our code to behave like spring does instead of using the dialect I think. But does having prepareConnection false /true effect performance . ? In other words we will gain any benefit by using readOnly=true now with with 4.1 since a readOnly connection is being passed on to the underlying connections
Thanks for the help.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Juergen Hoeller commented

This is indeed a performance benefit since the JDBC driver may enable significant optimizations for read-only connections, depending on the specific database. For example, on MySQL, this is necessary for reading from slave nodes in a master-slave scenario. In general, a DBMS may largely avoid the transaction log for read-only connections.

Note that we have been setting the connection read-only flag for many kinds of transactions before, including native use of Hibernate (i.e. HibernateTransactionManager). What changed as of 4.1 is simply that the Hibernate-JPA case (JpaTransactionManager) is being covered as well.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Mar 11, 2015

Venkat Srinivasan commented

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.