Local H2 Server-Client connection with DB running in memory - java

I have two independent Java apps which I would like to communicate with each other through an in-memory H2-DB. In theory very straight forward, but I cannot get the connection to work.
What I am trying to do:
I create an in-memory DB executing jdbc:h2:mem:test.
With the client(s), I try connecting to it. I tried jdbc:h2:tcp://localhost/~/test and similar connection strings, but all without success.
Is it possible to connect to an in-memory DB? What should the connection strings look like to make this work? Thanks a bunch.

After a ton of reading and trial-and-error with H2 options (http://h2database.com/html/features.html and http://h2database.com/html/advanced.html), I found that it is possible to access an in-memory database from multiple processes on the same machine (or remotely) using TCP/IP or SSL/TLS. The connection string for an in-memory database test is jdbc:h2:tcp://localhost/mem:test.

H2 database can be shared but not in memory, Your may please refer to official documentation:
http://h2database.com/html/features.html#auto_mixed_mode
First application with open it in embedded mode and other application will use server mode.

Related

H2 Database Auto Server mode : Accessing through web console remotely

I am fairly new to H2 Database. As a part of a PoC, I am using H2 database(version : 1.4.187) for mocking the MS SQL Server DB. I have one application, say app1 which generates the data and save into H2. Another application, app2, needs to read from the H2 database and process the data it reads. I am trying to use Auto Server mode so that even if one of the application is down, other one is able to read/write to/from the database.
After reading multiple examples, i found how to build the h2 url and shown as below:
jdbc:h2:~/datafactory;MODE=MSSQLServer;AUTO_SERVER=TRUE;
Enabled the tcp and remote access as Below:
org.h2.tools.Server.createTcpServer("-tcpAllowOthers","-webAllowOthers").start()
With this, I am able to write to the database. Now, I want to read the data using the h2-web-console application. I am able to do that from my local machine. However, I am not able to understand how I can connect to this database remotely from another machine.
My plant is to run these two apps in an ubuntu machine and I can monitor the data using the web console from my machine. Is it not possible with this approach?
How can I solve this ?
Or do I need to use server mode and explicitly start the h2 server? Any help would be appreciated.
By default, remote connections are disabled for H2 database for protection. To enable remote access to the TCP server, you need to start the TCP server using the option -tcpAllowOthers or the other flags -webAllowOthers, -pgAllowOthers
.
To start both the Web Console server (the H2 Console tool) and the TCP server with remote connections enabled, you will have to use something like below
java -jar /path/to/h2.jar -web -webAllowOthers -tcp -tcpAllowOthers -browser
More information can be found in the docs here and console settings can be configured from here
Not entirely sure but looking at the documentation and other questions answered previously regarding the same topic the url should be something like this:
jdbc:h2:tcp://<host>:<port>/~/datafactory;MODE=MSSQLServer;AUTO_SERVER=TRUE;
It seems that the host may not be localhost and the database may not be in memory
Is there a need for the H2 web console?
You can use a different SQL tool using the TCP server you have already started. I use SQuirreL SQL Client (http://squirrel-sql.sourceforge.net/) to connect to different databases.
If you need a web interface you could use Adminer (https://www.adminer.org/) which can connect to different database vendors, including MS SQL, which happens to be mode you're running H2. There is an Adminer Debian package that should work for Ubuntu.

What does JDBC Connection really mean? Wanted to know internals of the same

Is "opening the JDBC Connection" related to open a Socket with the DataBase software?
Databases provides connections to client eg. a GUI Administrative tool to manage related database like SQLyog for MySQL and so in JDBC connection we are requesting a connection from our application as client through JDBC API.
These connection as TCP connections so a client is required to know the port no and ip of the database server to talk to it.
what you must be wondering at is what is JDBC? if so then
JDBC is an interface provided by java that manages database operations and most awesome thing about this interface you will be writing exactly same code whether you are querying a MySQL or a PostgreSQL database servers.
It depends on what type of JDBC driver you are using. According to
http://en.wikipedia.org/wiki/Java_Database_Connectivity
you may have four types of JDBC drivers which usually (but not necessarily always) rely on TCP/Socket connections.
A JDBC connection can actually be anything - it's a generic way to talk to databases.
In most cases it is a TCP/IP connection but that is not always the case. For example you can embed a Derby Databse within your Java application and talk directly to that without even leaving your process.
If you find out what your database and driver is that should allow you to answer your question.
Here is what you require.This should answer all your queries. Cheers.

HSQLDB databases in SQL clients

I have a memory HSQLDB database with this connection URL:
jdbc:hsqldb:mem:test_database
It runs fine with my application but I need to configure this database in a SQL Client.
I can't because every clients complain that no host was found or there's no database.
I'm not sure if I'm filling all the information correctly in "host" and "database" fields or if it is a HSQLDB memory restriction.
Has anyone got the same error?? Thanks a lot.
With :mem: you define a database which is only accessible within the running java vm. This database resides in memory and cannot be accessed externally via host/port jdbc access.
Please read:
Running and Using Hsqldb
Advanced Topics
You can use the Database Manager provided by HSQLDB, just run in console
java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
and connect to the jdbc:hsqldb:mem:test_database

Java application connecting to replicated mysql databases

We have a java application that connects to mysql database. We are now going to change the database to replication mode by adding another DB instance. The idea is to provide DB high availability. The application should be able to switch to the standby DB in case it is unable to connect to the main database. One way to implement this is to maintain 2 sets of connections, keep monitoring both the databases and in case the app is unable to connect to the main DB, switch to the next set of connections and continue.
My question is is there a transparent way of switching the connections through mysql connector itself? OR is there any utility app that can sit between my app and the mysql connector and do this job?
To clarify , we are planning to do master - master replication. Both writes and reads happen frequently.
Yes, Connector/J (the MySQL JDBC driver) offers connection failover.
It's not trivial to set up, though. This should get you started.
http://dev.mysql.com/doc/refman/5.5/en/connector-j-usagenotes-j2ee-concepts-load-balancing-failover.html
#Mike Brant's point is good. If your data is write-infrequently / read-frequently, then you are best off only having your app write to a master DBMS, and read from a pool of slave DBMSs. It's good programming practice to use a different Connection for the parts of your app that write, and for those parts that will read the data. You can set up the read-only Connection with loadbalancing and failover, while leaving the write Connection pointing to the master.

How to save time when opening JDBC MYSQL connections

I have a very short Java application that just opens a connection to a remote MySQL database, reads some data, prints it, and exits. The most time-consuming part of the application is the database connection.
Currently I have only a single thread, and my only concern is to save the time of opening the connection.
I thought of several ways to make it faster, but it turned out they do not help:
Connection Pooling - doesn't help because the pool lives only only during a single run of the application. When the application is terminated, the pool is gone, and when I re-run the application, I have to re-open all the connections in the pool.
mysql-proxy - connects only to the local server: mysql-proxy for a remote MySQL server
TCP/IP server - I thought of holding a local TCP/IP server that will keep a persistent open connection and send it to a TCP/IP client on request. However, Connection objects cannot be serialized, so I have no way to pass the Connection object from client to server.
Any other option?
Generally connection to a DB is a most time-consuming operation. If the application is to be started and stopped then there is little that you can do.
Using connection-pooling in a web-server and call that by running your app which talks to the web server using JSON might be an option.
You said you have a very short application so your 3rd option might work if you put the database logic into you "option 3 TCP/IP server" and just forward the results to your connecting client. This is a typical application server pattern.
Another thing you should consider about network look up https://stackoverflow.com/q/3641155/1055715 which Marc B has mentioned in his comment.
It turns out the best solution is to use mysql-proxy with a script that handles connection pooling (a combination of my first two options). I found one such script here:
http://forge.mysql.com/tools/tool.php?id=151
It was probably written for an older version of mysql-proxy, so I had to fix it (if anyone need the fixed version - write me).
It works like a charm - I run the exact same application as before, the only change is in the connection string: instead of connecting to "qa-srv:3308" (the remote server) I connect to "127.0.0.1:4040" (the proxy server).

Categories