Singleton pattern is produced some problems when there are some updates - java

We have an Oracle database which hold data about some cities and
places, etc.
We have a web system which we can manipulate these datas.
We also have a desktop client application which is working with these
data.
For increasing our desktop application performance and decreasing unuseful request for our DAO layer, we have implemented some Singleton classes in our desktop application to fetch mentioned cities, places, etc data only once right after the user is opened his/her desktop application.
Recently we received a request from our clients why we don't see the changes we make using the web application, when the client desktop application is live and up and running. They're complaining about why they have to close the desktop app and open it again in order to see the changes.
We know that the problem is those Singleton classes but we don't want to change them because it's gonna be huge overhead in our system when they're not there. For solving the problem we have thought about multiple solutions:
Create a table in a database with integer column names similar to our data columns (cities, places, etc) and auto increment value when there's an update for tracking the changes using it (a light weight solution)
Using database functionalities
a Notify system that notify the client application whenever an update occurred.
a caching mechanism inside database that cache those lately changing tables and service our users when they have similar request
Here are our stacks:
Our Desktop application is swing application
Our Web application is JSF
Our business layer for both JSF and swing is EJB
Our Dao layer for both JSF and swing is Eclipse-Link
What do you think is the best practice for solving this problem ?

Oracle has a feature called "Database Change Notification" that can be used to be notified when read-mostly tables are changed. It looks like this feature could be a good fit to address your requirement. The link to the doc is here.
In a nutshell, the way it works is that JDBC thin driver in your desktop application would open a port and the Oracle Database would connect to that port and use this connection to push notifications when data changes. You then get a callback through an event/listener API and can refresh your cache.
This notification mechanism is designed for data that is read-mostly, in other words, data that doesn't constantly change otherwise it wouldn't be worth caching the data anyway.

Related

Synchronize tables in SpringBoot multitenant architecture

I have a SpringBoot application running on a multitenant architecture.
I've two databases Admin and Client (both are MySQL) and both these databases have a User table
Client can add users to the User Table but I need them to get synchronized in the User table of Admin database.
Is there a way I can achieve this?
I've read about flyway migrations but I think it works more on database schema changes and not values.
Please ignore my mistakes as this my first question, any help would be appreciated.
This looks like a solution to your problem:
SymmetricDS is software that replicates relational database tables between multiple databases. It can also be used to replicate files and directories between multiple hosts. It uses a light-weight, web-based protocol to send and receive data, which makes it easy to work with firewalls. Replication is done in the background asynchronously, allowing data changes in offline mode. It supports most commercial and open source database platforms.
How does it work?
Triggers are installed in the database to guarantee that data changes are captured. This means that applications continue to use the database as usual without any special driver software. The triggers are written to be as small and efficient as possible. Routing and syncing of data is done outside of the database in the SymmetricDS process.
SymmetricDS supports many databases and can replicate across different databases, including Oracle, MySQL, MariaDB, PostgreSQL, MS SQL and many more.
https://www.symmetricds.org/docs/faq
You need to create some event from the flow where client adds user to the User Table.
If this "client" flow is in same java service then you can make use of Spring's Asynchronous Event Handling or have a method(which does the data copy) marked with #Async. This ensures the data copy happens in separate thread.
If the "client" flow is in different java service, then any publisher-subscriber model can be used (some opensource frameworks available are kafka, rabbitmq etc).
Now to connect to two datasources at the same time, Spring's RoutingDataSource will come handy in this scenario as it works on "lookup key" to choose the datasource. Or else you can hardcode two datasource beans in your config (since it is fixed in your case).

Storing a Database Online to be Accessed by GUI in Java

I want to create a data management system which will be used via a GUI, by many users in different locations. I want to use client/server connections when a user logs into the GUI, and then whenever anything is added/updated, the database is updated accordingly. I am wondering firstly, if this architecture is logical and will work? And secondly, whether I need to store the database online, or if it can be stored locally and then accessed by people online using the GUI? The database is currently in MS Access however I can migrate to another program if it will make things easier.
I am doing the GUI in Java and will use JDBC to access the database.
There's no 'best' option, but a good solution would be to develop some web services that channel traffic to and from the database, then have your GUI call those web services.
That way you can control access far more easily, as well as ensuring data integrity by having the web service perform validation and sanity checks.
i would suggest you use mysql database your connection is something like this in java jdbc
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://remoteUri/database-name?"
+ "user=user&password=userpw");
Yes, it is possible. Firstly you have to create a database (I would recommend Oracle). Then in your GUI you can connect to the database and each button in your GUI will do certain SQL statements that will alter the data in the database.
A good website I found is : http://www.homeandlearn.co.uk/java/java_and_databases.html

Java Swing - Single user application to a Multi user application

I am a newbie......I have a Java Swing application and it runs great on my machine. I want to access this application from a Server via Citrix. So when I click on the published icon, it would run the main method in the jar file and will enable me to access the application. This application will be able to access a DB in the DB Server.
But I want mutliple users to access the application at the same time and that is where my questions are:
I thought of creating n number of threads available for n number of users (i.e.) I can set a limit on concurrent access. But what will be the entry point.....I mean when I click on the published icon, it means each time the main method will be invoked.
I can think of seperating my User Interface from the Logic layer....but I have no idea how to do it. ofcourse I am following MVC model. My question is in terms of creating multiple instances of the gui each time the application is accessed.
And finally I want to use DB Connection pooling. So, would this mean that I have to create a separate java program that creates this pool and my application will use its datasource?
Can anyone please 'point' me in the right direction? I am not looking for specific ideas but just an idea on how to create this multi user application.
Typically, for a multi-user Swing application you would want to separate the "client" part of the application from the "server" application.
This works as follows:
Each user would get their own running instance of the client application. This can be on their own machine.
The server application is a single instance (or maybe a cluster) that accepts connections from multiple clients and talks to the database
The client applications talk to the server application when they need to access or change data. There are a wide variety of different communication methods you can use.
Optionally, the server application can send notifications to the client (e.g. in situations where data is updated by another client)
You can do without the server application if you are happy to let the clients connect to the same database. This is simpler to set up, but has some downsides:
You need to be much more careful about concurrent access to the database / potential corruption from different clients attempting to alter the same data at the same time.
You need to allow connections to your database, from clients that are potentially untrusted. This is a security risk.
Given that you already have a working application, the second option is probably easier for you to move to. Just be aware of the downsides: the first option is a much better architecture in general.

How do you store and replay JDBC statements?

Given a JDBC-based application, that was not designed for real-time propagation of changes from one instance of the app running on computer A to another instance runnning on computer B in a two-way synchronization schema. How can you do this elegantly, without using Symmetric DS?
We though of using XMPP and XStream, transforming POJOs to XML or JSON, sending them via the XMPP, Smack API to the pre-configured "chat room" where other bots, listening, would replay the data they receive. Thus, even offline client apps, would receive the "DiscussionHistory" by sending their last "since timestamp".
I kind of looked everywhere for a "near real-time database change propagation" in Java, or even in H2, but where changes are propagated between each node registered, but the only solution I could think of is to use the XMPP protocol, build a "bot" chat-room around it, have nodes send their data there while others listen for changes.
The so-called "bots" are application instances on different computers, of an accounting application that should allow for real-time collaboration on the same database, but allow for offline modifications (so no centralized server to store changes).
One common approach is to build your caching so that the application always queries the database if a particular entry is not found. Then you would only have to synchronize cache-evictions to force all nodes in a group to re-load a certain entry. This is fairly easily achieved using, for instance, spring method caching and ehcache.

Two different Java applications sharing the same database

In my web application I have a part which needs to continuously crawl the Web, process those data and present it to a user. So I was wondering if it is a good approach to split it up into two separate applications where one would do the crawling, data processing and store the data in the database. And the other app would be a web application (mounted on some web server) which would present to a user the data from the database and allow him a certain interaction with the data.
The reason I think I need this split is because if I make certain changes to my web app (like adding new functionalities, change the interface etc.) I wouldn't like the crawling to be interrupted.
My application stack is Tapestry (web layer), Spring, Hibernate (over MySQL) and my own implementation of the crawler independent from the others.
Is it good for the integration to be done just by using the same database? This might cause an issue with accessing the database from the both applications at the same time. Or can the integration be done on the Hibernate level, so both applications could use the same Hibernate session? But can the app from one JVM instance access the object from another JVM instance?
I would be grateful for any suggestions regarding this matter.
UPDATE
The user (from web app's interface) would enter the URLs for crawler to parse. The crawler app would just read the tables with URLs the web app populates. And vice versa, the data processed by the crawler would just be presented on the user interface. So, I think I shouldn't concern about any kind locking, right?
Thanks,
Nikola
I would definitely keep them separated like you are planning. The web crawling is more a "batch" process than a request driven web application. The web crawling app will run in its own JVM and your web app will be running in a servlet/Java EE container.
How often will the crawler run or is it a continuously running process? You may want to consider the frequency based on your requirements.
Will the users from web app be updating the same tables that the crawler will post data to? In that case you will need to take precaution otherwise a potential deadlock may arise. If you want your web app to auto refresh data based on new inserts in the tables then you can create a message driven bean (using JMS) to asynchronously notify the web app from the crawler app. When a new data insert message arrives you can either do a form submit on your page or use ajax to update the data on the page itself.
The web app should use connection pooling and the batch app could use DBCP or C3P0. I am not sure you gain much benefit by trying to share the database sessions in this scenario.
This way you have the integration between the two apps while not slowing down each other waiting on other to process.
HTH!
You are right, splitting the application into two could be reasonable in your case.
Disadvantages of separating into two applications -
You can not cache in Hibernate or any other cached mutable objects that are modifiable from both applications in any one of them. Optimistic locking should work fine with two hibernate applications. I don't see any other problems.
Advantages you have already specified in your code.

Categories

Resources