p6spy disturb Routing Datasource to Read-Only Database
uHan2 opened this issue · 5 comments
hello im using 1.5.8 version.
and this is call stack snapshot in debug mode on intelliJ
as you can see, the step is
start transaction -> get connection on datasource -> "get connection and get MetaData by p6spy" -> determineCurrentLookUpKey (Actual Routing point)
in my expect, the next step of determineCurrentLookUpKey (Actual Routing point) is get new connection
but it use the connection which was get by p6spy.
when if i remove this dependency, it works fine.
so how can i solve this issue? thank you :)
Hey, I don't quite understand what is the problem that you're seeing. The fact that you see p6spy connection is expected as it proxies the actual connection, but all the operations are still going through your RoutingDataSource
.
Can you please provide an example of something not working (i.e. query goes to a wrong route or some exception)?
Here is DataSource Type. as you can see i wrapped AbstractRoutingDataSource by LazyConnectionDataSourceProxy
boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
this code Is a condition that transaction is readonly or not
and this is a partial of AbstractPlatformTransactionManager
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
at this line, transaction is set readonly or not
the normal step is
TransactionSynchronizationManager.setCurrentTransactionReadOnly() -> TransactionSynchronizationManager.isCurrentTransactionReadOnly()
but, when i use p6spy,
TransactionSynchronizationManager.isCurrentTransactionReadOnly() comes first (i think because p6spy should get connection) -> TransactionSynchronizationManager.setCurrentTransactionReadOnly() -> X (not going to TransactionSynchronizationManager.isCurrentTransactionReadOnly())
i think the transaction manager use the connection which already get by p6spy
when i remove p6spy, it works normally
im korean and my english little poor. I ask for your understanding. thank you :)
Thanks for the example, it seems to be more complicated that I initially anticipated so I will have to allocate some time to get to it and find a reason. I'm quite busy at the moment, so I won't be able to provide any ETA.
Meanwhile I think one way you can workaround that is to exclude your lazy/routing data source from decoration using decorator.datasource.exclude-beans: dataSource
and instead rely on decoration of primaryDataSource
and readonlyDataSource
(so that each will be wrapped into individual P6DataSource
), but keep in mind that they have to be spring beans to pass through decoration phase.
im korean and my english little poor. I ask for your understanding. thank you :)
No worries 🙂 I could understand you well. And thank you again for the detailed explanation!
thank you for your answer :)
i will try later that way you suggested.
If you solve this problem later when you have time, please mention me on this issue. thank you 👍
oh my god .. it works!
I'm not sure I fully understand what you're saying, but i tried below things
- add
decorator.datasource.exclude-beans: getDataSource
in my application.yml (in my case the bean name is getDataSource) - make primary Database and readonly Database to spring beans
and it works! but It's hard to understand why this is working normally
two datasource was not a spring beans when i issue it. and now it becomes beans so is it wrapped into p6Datasource each?
and i exclude my origin datasource which return new LazyConnectionDataSourceProxy(routingDataSource);
then i wonder how spring routing my transaction...
it works but it hard to understand why..
If you don't mind, I'll ask you to explain. and really appreciate for your hint to solve