How do I write in two different databases in Spring Boot? - java

I need to make a REST API so two components can communicate with each other.
The flow starts like this:
Component 1 sends a request
The API processes it and, if everything's correct, writes inside Component 2 DB
Various data processing...
Component 2 sends a request
The API processes it and, if everything's correct, writes inside Component 1 DB
How do I make this appen in Spring Boot? I don't need any domain class, so I don't think I need to use JPA.
Update: I need to make it work with JdbcTemplate
Thanks in advance

I'm not sure what you intend to achieve here but this is what I would suggest you do if you really need to achieve this with JDBC template.
In your configuration file: e.g application.properties, you could specify keys to hold values used in configuring every different connection to the databases you need to interact with. A naive example could be:
app.datasource1.url=...
app.datasource1.driver=...
app.datasource1.username=...
app.datasource1.password=...
app.datasource2.url=...
app.datasource2.driver=...
app.datasource2.username=...
app.datasource2.password=...
You could create beans of these connections in a config class and differentiate them with names (qualifiers), one of them could be a tagged primary data source and the other a secondary data source. As an alternative, however, you can do 3 each time you need an instance of the DB connection.
Since you are using the JDBC template, in the service classes or implementations where you make calls to the database, you could start first by creating a connection (an instance of JDBC Template) before using it.
With this approach, you can create as many connections as you want to as many DB as you want. Don't know if this helps.

Related

Any patterns to follow to share huge DB data over REST

I have a situation where I need to share huge data (probably in billions) over REST. Any particular design pattern to follow. I read something about scrolls that are available in Elastic where we can initialize the scroll once and then use it to retrieve subsequent data in batches.
I have using MySQL database where all my data is stored and i need to share all the data over REST services. I am using Spring BOOT for REST.
I have thought of a way where I open a connection and starting getting the data and write in a blocking queue in a producer consumer pattern and then give back a handle (id) to client for subsequent calls to get next batch.
Is there a better way to achieve the same.

How to use multiple data-source (one for read and another for write) within a single transaction in Spring?

I have configured two databases. One for read (Read-Only), other for Read-Write operations. I have service which involves both read and write operations. I would like to use the read-only db for all read operations and the other db for write operations. How could I achieve this with Spring transactions. I've implemented annotation based approach which changes the datasource using AbstractRoutingDataSource. But, everytime I need to create a new transation using propogation=Requires_New. Is there a better way to do this?
#DbSource(DbType.READ_REPLICA)
#Transactional(propogation=Requires_New)
public Object readData(long id) {
return dataDao.find(id);
}
You should create seperate spring configurations for both of your datastores together with TransactionManager beans. At least one of these beans should have name value so you can use proper transactional manager when needed:
#Transactional(transactionManager="DS1transactionManagerBeanName")
// DS1dataStoreRelevant class/method
Of course combining logic which uses both data stores in single transaction is not possible with JpaTransactionManager. If this is what you are looking for you should consider using distributed JtaTransactionManager provided by web container like IBM WebSphere or other like Atomikos/Bitronix etc. which provides you with transactionality between different data stores (XA resources in general).
Some possible workaround in certain cases (like Oracle datastores) would be to provide visibility from one database to other and use single data store/transaction manager but I am not entirely sure how it works underneath on the database side.
The most basic solution would be just to not mix logic impacting each of the data store and arrange it in sequential transactions but as said whole chain of operations won't be transnational itself so possible rollback would apply only to current transaction (no rollback to the ones committed earlier). It would require some extra logic to introduce rollback/retry policy with dirty flags etc.

DAO with different DataSource for different cases

I access a REST API to get some objects in order to save them in a local DB. Later I want to access these objects in the local DB and update them as well.
I'm not sure what is the best way to go - trying to use the DAO Design Pattern. What I see is, that there are different data sources for different cases (operations).
Can you give me some ideas?
First advice: do NOT overcomplicate your solution if it's not necessary.
If you are using the same DB instance for read and write operations, just create single pair of the DAO interface\implementation for all operations
Additionally, API call should NEVER reach data access layer directly. Add business service layer in between.
API -> Business Service(s) -> DAO -> DB

How to structure code when connecting to databases

I am developing a program in Java that I will use for registering data. I store the data in a MySQL database. We have not been making "big" programs in my class that uses databases for storage so what we have done is to make an adapter(We usually name it DBAdapter or something) that creates the connection and returns it. Then we have made a database handler class where all the statements are being executed. Then last the controller + view class have a reference to this handler and call whatever methods available.
However, my question is: When dealing with multiple tables and maybe different model data wouldn't it be good to separate the code in the handler into smaller chunks? Such as private classes or other public classes that a "main" handler could have references too? Example: If you make a system for a company that ship goods you probably would have a database that stores data about the goods. Then you would have a handler that has many select-statments for various stuff. You would also have many employees and then you probably want to separate the select-statements for the goods from the select-statements for the employees.
I also wonder if handler/adapter etc. is the correct terminology?
(This is not homework btw. I am making a program that will be a used for registering data for my iPhone app)
Thank you for your time.
You may want to look into Object-relational mapping libraries for Java, such as OpenJPA or Hibernate. If you'd rather stick to SQL - or like the fine-grained control - you may find Ibatis interesting.
In any case, I wouldn't manage the connections to the DB myself but rely on a connection pool, usually accessed through the DataSource interface.
While ORM may well be where you head, I'd start with
a connection pool
implementing a DAO pattern strategy. If you are using Spring, look at JDBCTemplate - it will be pretty easy to convert this to HibernateTemplate, etc.

Multiple transaction managers in spring and select one at runtime

For each client, I have separate databases but business logic and tables are same for each client. I want common service and dao layer for each client. In dao, I select datasource based on logged user client. In #Transactional, I have to pass bean id of transaction manager. How to make common service layer with #Transactional annotation.
Same question is here
Multiple transaction managers - Selecting a one at runtime - Spring
Choose between muliple transaction managers at runtime
but nobody reply
If you want to create a database connection dynamically, then have a look at this SO post.
From the post linked : Basically in JDBC most of these properties are not configurable in the
API like that, rather they depend on implementation. The way JDBC
handles this is by allowing the connection URL to be different per
vendor.
So what you do is register the driver so that the JDBC system can know
what to do with the URL:
DriverManager.registerDriver((Driver)
Class.forName("com.mysql.jdbc.Driver").newInstance());
Then you form
the URL:
String url =
"jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]"
And finally, use it to get a connection:
Connection c = DriverManager.getConnection(url);
In more
sophisticated JDBC, you get involved with connection pools and the
like, and application servers often have their own way of registering
drivers in JNDI and you look up a DataSource from there, and call
getConnection on it.
In terms of what properties MySQL supports, see here (The link is dead).
EDIT: One more thought, technically just having a line of code which
does Class.forName("com.mysql.jdbc.Driver") should be enough, as the
class should have its own static initializer which registers a
version, but sometimes a JDBC driver doesn't, so if you aren't sure,
there is little harm in registering a second one, it just creates a
duplicate object in memeory.
I don't know if this will work, since I have not tested it, but you
could try.
Now what you could do is, use the #Transactional annotation on top of the DAOs without specifying any values (That works). Now in your DAO classes, instead of injecting any DataSource bean, create your own dataSource dynamically as specified in the above link and then either inject that dependency at runtime, use getter setter methods, or just use the new keyword. I hope that'd do the trick.
NOTE: I have not tested it myself yet, so if this works, do let me know.
You do not need to configure and switch between multiple transaction managers to accomplish your end goal. Instead use the Spring provided org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource mechanism.
Detailed examples can be found here :
https://spring.io/blog/2007/01/23/dynamic-datasource-routing/
http://howtodoinjava.com/spring/spring-orm/spring-3-2-5-abstractroutingdatasource-example/

Categories