I want to use HA-JDBC over a set of database nodes which use their own replication mecanism.
I've read here that this is not recomended, but I only need the provided load balancing feature.
How can I achieve this? HA-JDBC's transaction mode configuration only allows to chose between 'parallel' and 'serial'. I've already searched through HA-JDBC's source for a simple way to disable replication but without success. I guess it's related to INVOKE_ON_MANY strategy, but where and how can I disable it?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can still use HA-JDBC for read-only connections, but your write statements should not use HA-JDBC - otherwise you will lose transaction isolation semantics.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I only need to care about sending the reads to the the replica where writes of the same transaction where sent, the rest is handled by my replication engine.
I am by now using the same code from 'executeQueryMethod' condition for writes and it seems working with some simple testing.
But the unit tests fail with a 'SQLNonTransientConnectionException', so I am worried about this being a naive approach and not working properly.
Thank you in advance for your help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The downside to this approach is that a failure of the database on which a given transaction will need to propagate back to the client. You cannot safely failover to another database mid-transaction, since the transaction context is lost.
"I only need to care about sending the reads to the the replica where writes of the same transaction where sent"
How do you intend to achieve this? Simply changing Statement.executeUpdate()/executeBatch() methods to be load balanced does not achieve this. You would need to associate a transaction with a database, and force all statements for that tx to use that database.
Also, if you change core behavior of HA-JDBC in this way, don't expect the unit tests in their current state to pass.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The idea is to associate a transaction with a database. If a failure occurs, then start a new transaction with the next database.
The same way HA-JDBC fails over from one primary to another, it should be possible to do the same using databases from load balancer.
In terms of 'hacks', I guess it just means picking a database from load balancer, instead of using the master, and disabling propagation (on success).
Sorry if I'm missing some point.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What about data that was written to the transaction that failed? Do you intend to replay those statements? I don't see how you can do that without losing transaction isolation. What if those writes were conditional based on reads that are no longer valid?
Also, is this replication mechanism synchronous? If not, you no longer have transactional consistency.
I'm not saying you can't modify HA-JDBC to achieve what you're looking for - only that such a solution would have to sacrifice transactional guarantees for HA.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
JDBC methods within HA-JDBC proxies are hard coded to use specific invocation strategies, so I don't think you have no other choice than to fork the HA-JDBC code base.
You can associate a tx with a database by adding the database as a property of the transaction context.
Given the inability to maintain availability during mid-transaction failures, I have to wonder, what advantages does this replication mechanism have over vanilla HA-JDBC?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
can you post details on what changes to be made to disable write replication? I made changes to InvokeStrategies code --> INVOKE_ALL with InvokeOnOneInvocationStrategy..
Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I want to use HA-JDBC over a set of database nodes which use their own replication mecanism.
I've read here that this is not recomended, but I only need the provided load balancing feature.
How can I achieve this? HA-JDBC's transaction mode configuration only allows to chose between 'parallel' and 'serial'. I've already searched through HA-JDBC's source for a simple way to disable replication but without success. I guess it's related to INVOKE_ON_MANY strategy, but where and how can I disable it?
You can still use HA-JDBC for read-only connections, but your write statements should not use HA-JDBC - otherwise you will lose transaction isolation semantics.
I only need to care about sending the reads to the the replica where writes of the same transaction where sent, the rest is handled by my replication engine.
I am by now using the same code from 'executeQueryMethod' condition for writes and it seems working with some simple testing.
But the unit tests fail with a 'SQLNonTransientConnectionException', so I am worried about this being a naive approach and not working properly.
Thank you in advance for your help.
The downside to this approach is that a failure of the database on which a given transaction will need to propagate back to the client. You cannot safely failover to another database mid-transaction, since the transaction context is lost.
"I only need to care about sending the reads to the the replica where writes of the same transaction where sent"
How do you intend to achieve this? Simply changing Statement.executeUpdate()/executeBatch() methods to be load balanced does not achieve this. You would need to associate a transaction with a database, and force all statements for that tx to use that database.
Also, if you change core behavior of HA-JDBC in this way, don't expect the unit tests in their current state to pass.
The idea is to associate a transaction with a database. If a failure occurs, then start a new transaction with the next database.
The same way HA-JDBC fails over from one primary to another, it should be possible to do the same using databases from load balancer.
In terms of 'hacks', I guess it just means picking a database from load balancer, instead of using the master, and disabling propagation (on success).
Sorry if I'm missing some point.
What about data that was written to the transaction that failed? Do you intend to replay those statements? I don't see how you can do that without losing transaction isolation. What if those writes were conditional based on reads that are no longer valid?
Also, is this replication mechanism synchronous? If not, you no longer have transactional consistency.
I'm not saying you can't modify HA-JDBC to achieve what you're looking for - only that such a solution would have to sacrifice transactional guarantees for HA.
Yes, my replication mechanism is synchronous, that should not be a problem.
I guess I will have to abort those transactions, on wich a failure occurs.
In that case, I need to use INVOKE_ON_NEXT strategy when;
- a statement is on autoCommit or
- a statement is the first of a transaction
My code is already working for autoCommit-enabled cases.
In the later case, I need some form to associate the selected database to the transaction.
How you suggest to apply those modifications to the code?
Would it be easier to create a new invocation strategy?
JDBC methods within HA-JDBC proxies are hard coded to use specific invocation strategies, so I don't think you have no other choice than to fork the HA-JDBC code base.
You can associate a tx with a database by adding the database as a property of the transaction context.
Given the inability to maintain availability during mid-transaction failures, I have to wonder, what advantages does this replication mechanism have over vanilla HA-JDBC?
The advantages would be to profit from my replication mechanism including provided metrics to use on a custom balancer.
I've already forked the project and added my modifications for non-replicated writes and transaction context compliance.
Thank you for your help.
Last edit: André Costa 2014-05-28
can you post details on what changes to be made to disable write replication? I made changes to InvokeStrategies code --> INVOKE_ALL with InvokeOnOneInvocationStrategy..
Thanks