I have an application that uses Hibernate/JPA, with Spring and Jersey. In my application context I set the data source, define an entity manager factory, set the transaction man
I have the same kind of need : route the connection between a readonly and writeonly database using a classical MASTER / SLAVE to scale reads.
I end up with a lean solution, using the AbstractRoutingDataSource base class from spring. It allows you to inject a datasource that routes to several datasources based on some conditions that you write.
And my router simply looks like the following :
public class ReadWriteDataSourceRouter extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "READ"
: "WRITE";
}
}
I find this quite elegant, but the problem here is that Spring seems to set the transaction to readonly after injecting the datasource, so it does not work. My simple test is to check the result of TransactionSynchronizationManager.isCurrentTransactionReadOnly() in my readonly methods (it is true), and in the determineCurrentLookupKey() method where it is false on the same call.
If you got ideas... Anyway you could base the test on anything else other than TransactionSynchronizationManager and this will work fine.
Hope this helps, Christophe