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

Document LazyConnectionDataSourceProxy for IsolationLevelDataSourceRouter usage with DataSourceTransactionManager #19688

Closed
spring-projects-issues opened this issue Jan 10, 2017 · 8 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: documentation A documentation task
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

springrain opened SPR-15121 and commented

IsolationLevelDataSourceRouter.determineCurrentLookupKey returns the result was null, since AbstractPlatformTransactionManager.getTransaction (TransactionDefinition definition) before calling doBegin(Object transaction, TransactionDefinition definition), setCurrentTransactionIsolationLevel(Integer isolationLevel) is not set, but get a connection, it's bug.


Affects: 4.3.4

Referenced from: pull request #1291

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

IsolationLevelDataSourceRouter is primarily intended for JTA scenarios where Connection lookups only happen after transaction begin. With DataSourceTransactionManager, the isolation level is applied to the retrieved Connection directly, so it is not really designed to interact with such DataSource-specific isolation setup.

Are you trying to optimize the switching overhead there? Why are you using IsolationLevelDataSourceRouter to begin with?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jan 10, 2017

springrain commented

I used to read and write the database separation,I don't have to use JTA

<bean id="dataSource" class="org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter">
<property name="targetDataSources">
<map>
<entry key="ISOLATION_READ_UNCOMMITTED" value-ref="dataSourceWrite"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceRead"/>
</bean>

@spring-projects-issues spring-projects-issues added status: waiting-for-triage An issue we've not yet triaged or decided on in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement and removed type: enhancement A general enhancement labels Jan 11, 2019
@andrei-ivanov
Copy link

I've hit a similar issue, where I'm trying to use the readOnly status of the transaction to determine which dataSource to use, just to see that AbstractPlatformTransactionManager#prepareSynchronization is invoked just after doBegin, which obtains the connection (using a JpaTransactionManager) 😥

@andrei-ivanov
Copy link

is there any chance that moving the prepareSynchronization call before doBegin might work?

@andrei-ivanov
Copy link

@jhoeller ?

@lukago
Copy link

lukago commented Oct 27, 2021

I have similar problem to @andrei-ivanov, any updates on this? @jhoeller

@jhoeller jhoeller self-assigned this Nov 22, 2021
@jhoeller
Copy link
Contributor

Returning to DataSource setup issues for a bit of a JDBC theme in 6.1.2, including new sharding support and several refinements to Spring's DataSource adapters : see https://github.com/spring-projects/spring-framework/issues?q=is%3Aopen+milestone%3A6.1.2+label%3A%22in%3A+data%22+

I am inclined to address the isolation level scenario here through an extension of SmartDataSource with a dedicated getConnection(int isolationLevel, boolean readOnly) method that DataSourceTransactionManager can call if the target DataSource implements it. IsolationLevelDataSourceRouter and a similar routing DataSource based on @Transactional(readOnly=...) can then take this into account directly when specified. This would allow us to preserve the semantics of our existing transaction synchronization arrangement which we cannot easily bend towards earlier exposure.

As an alternative, LazyConnectionDataSourceProxy could be used to approach JTA-like late retrieval semantics which should make the existing transaction synchronization arrangement work with IsolationLevelDataSourceRouter as the target behind a LazyConnectionDataSourceProxy, since the actual target Connection will be retrieved after transaction begin then.

@jhoeller
Copy link
Contributor

jhoeller commented Dec 1, 2023

Experimenting with a few scenarios here, such an extension to SmartDataSource is rather involved in more complex setups, e.g. behind a JPA provider. In comparison to that, LazyConnectionDataSourceProxy is actually the simplest solution out: configuring both your transaction manager and your data access setup (JdbcTemplate or JPA setup) with a LazyConnectionDataSourceProxy conveniently allows for IsolationLevelDataSourceRouter to pick up a late-bound current isolation level within the transaction. And this comes with the extra benefit that connection contention is minimized and even avoided completely (with no connection ever fetched) for "empty" transactions which is quite common with JPA queries that can be answered from a cache.

As a consequence, I am going to turn this ticket into a documentation ticket for LazyConnectionDataSourceProxy.

@jhoeller jhoeller changed the title IsolationLevelDataSourceRouter does not work with DataSourceTransactionManager [SPR-15121] Document LazyConnectionDataSourceProxy for IsolationLevelDataSourceRouter usage with DataSourceTransactionManager Dec 1, 2023
@jhoeller jhoeller added type: documentation A documentation task and removed type: enhancement A general enhancement labels Dec 1, 2023
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: documentation A documentation task
Projects
None yet
Development

No branches or pull requests

4 participants