There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Jayesh A Lalwani wrote:You need to use AbstractRoutingDataSource provided by Spring. Look at this blog that does something very similar to what you want to do.
The 2 minute explanation of this is that there is a context that is tied to a thread local variable. The AbstractRoutingDataSource encapsualtes a map of real data sources. It looks at the TL context to determine which datasource to route too. So, whenever he switches the context all consecutive calls go to the data source that is tied to that context.
The sample on the blog might make it clearer that my very short explanation, because it has real example. GO through the example carefully.
Jayesh A Lalwani wrote:If you are already under spring and using standard Spring mechanisms to build your DAO code, then this is the approach is the simplest and best. Since Spring is managing your database connection, you need to tell Spring to switch the underlying DB connection, and this is the best way of doing it
If you were doing something non-standard, other approaches might be better. It's hard to say without looking at what exactly you are doing
Note that there is an inherent problem with how Spring models the DAO support that it assumes that you prefer to have ORM; ie; each DAO queries database and returns objects, and from the application layer you modify the objects and return them back to DAO. Although, this is good for most webapps, where the number of objects loaded at a time tend to be small, you will run into trouble if you have lot of data. If you have like 1 billion rows that you want to "publish", you are just not going to have enough memory to load all these objects into memory. You might have to think about batching your publishing, and/or using native database utilities rather than do it in Java, or investigating in using a a full fledged ETL utility. I'm getting a little ahead of your question here, and this might not be applicable to your case. Just trying to make sure that your approach might have potential pitfalls.
Jayesh A Lalwani wrote:Ahh ok.. got it. So, the "publishing" itself is outside of your application. You just need to switch when the publishing is done. Got it. Apologies if I missed it earlier
Yes, AbstractRoutingDataSource is perfect for you. However, note that there might be a slight hiccups during the switch
a) You will have to ensure that the data in your original database is "read only" during the publishing. Because, when the switch occurs, and if from the perspective of the user, some data is lost, it would be very weird.
b) Depending on how the AbstractRoutingDataSource is implemented, you will have some connections going to the old database and some connections going to the new database at the same time. You won't be able to get the old database offline immediately after the switch occurs. For example, if your AbstractRoutingDataSOurce is deciding to switch based on a TL variable, and the TL variable is initialized at the start over every HTTP request, then at the moment the switch occurs, the HTTP requests still being serviced will still open connections to old database. OTH, if the the TL variable is initialized from something that is stored in the HTTP session, then the app will be opening connections to the old database as long as the sessions are alive
For the most part, you still want to do switches during periods of low activity, even though you would design it to be seamless to the user.
There are 10 kinds of people in this world. Those that understand binary get this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
|