I created a simple SQLite connection using Java.
Now I want to activate MySQL simultaneously as an option to store the data online.
Is there an easier way than rewriting every method to use the MySQL connection? E.g. create a connection object with both JDBC Drivers at once, so I have only one connection variable?
E.g. create a connection object with both JDBC Drivers at once, so I have only one connection variable?
Short answer: No. You cannot use a single JDBC Connection object to update two completely different database systems. You couldn't even use a single JDBC Connection object to update the same type of database (e.g., SQLite or MySQL) in two different places unless you had some sort of replication enabled between the databases themselves.
If you re-vamped your code to work with your own custom Objects (Classes) then you could conceivably code those classes to persist the data in SQLite and/or MySQL, but that would still require separate connections to each database.
Related
Is it possible to start up and shut down multiple H2 databases within a JVM?
My goal is to support multi-tenancy by giving each user/account their own database. Each account has very little data. Data between the accounts is never accessed together, compared, or grouped; each account is entirely separate from the others. Each account is only accessed briefly once a day or a few times a month. So there are few upsides to housing the data together in a single database, and some serious downsides.
So my idea is that when a user logs in for a particular account, that account’s database is loaded. When that user logs out, or their web app session (Vaadin app) times out, that account’s database is closed, it's data flushed to storage, and possibly a backup performed. This opening and closing would be happening for any number of databases in parallel.
Benefits include minimizing the amount of memory in use at any one time for caching data and indexes, minimizing locking and other contention, and allowing for smooth scaling.
I'm new to H2, so I'm not sure if its architecture can support this. I'm asking for a denial or confirmation of this capability, along with any tips or caveats.
Yes it is possible to do so. Each database will contain its own mini environment, no possible pollution between databases.
You could for example use a jdbc url based on the user id or login from the user:
jdbc:h2:user1 in H2 1.3.x embedded mode
jdbc:h2:./user1 in H2 1.4.x embedded mode
jdbc:h2:tcp://localhost/user1 in tcp mode
You can use any naming convention for the database name, provided your OS allows it: user1, user2, etc... or truly the name of the login.
Tips:
use the server mode rather than the embedded mode, allowing for same user multiple connections from multiple sessions/hosts
have a schema migrator (like flyway) to initialize each newly created db
ensure you manage name collisions at the top level of your app, and possibly store these databases and corresponding logins in a dedicated database as well
Caveats:
do not use a connection pool as connections will be difficult to reuse
You must make sure IFEXISTS=TRUE is not used on the server
avoid using tweaks on the jdbc url, like turning LOG=0, UNDO_LOG=0, etc...
I do not know if you'll have a limitation from your OS or the JVM on how many db files could be opened like this.
I do not know if such setting can be tweaked from the manual pages. I could not find one.
Please refer to H2 manual in doubts of url parameters.
I have a piece of j2EE app that runs on Jboss AS 4.2.3 and has a lot of reads to a mysql db.
I'd like to setup several more mysql instances, so the app will be able to decide which to contact.
we are using Hibernate as the ORM (full JPA support).
I've been looking at Hibernate Shards, and OpenJPA - but perhaps there is another way to do it?
is there a way we can still use JPA (so we won't need to change our code) and have some kind of read balancing as the provider?
I can pull some tricks on the hosts file, use a DNS with short TTL - but am looking for a simpler solution.
is there one?
just to make sure, sharding is not interesting at this point. just reading.
So eventually what i did was to extend mysql jdbc driver and modified the mysql-ds.xml file.
in the xml file i changed the connection string to contain several hosts, and the :mysql: to :myjdbc:, and entered my class as the provider.
in the JDBC driver i extended i've had to parse the connection string in two functions:
1. acceptsURL
2. connect
my code parses the connection string, selects a machine randomly, and calls the super function with a revised legal connection string.
and it just worked!
if a mysql read replica failed, then the connection fails, and on the next attempt a different machine is chosen.
whooohooo!
do you have any comments?
Is there a way that I can use JDBC to target multiple databases when I execute statements (basic inserts, updates, deletes).
For example, assume both servers [200.200.200.1] and [200.200.200.2] have a database named MyDatabase, and the databases are exactly the same. I'd like to run "INSERT INTO TestTable VALUES(1, 2)" on both databases at the same time.
Note regarding JTA/XA:
We're developing a JTA/XA architecture to target multiple databases in the same transaction, but it won't be ready for some time. I'd like to use standard JDBC batch commands and have them hit multiple servers for now if its possible. I realize that it won't be transaction safe, I just wan't the commands to hit both servers for basic testing at the moment.
You need one connection per database. Once you have those, the standard auto commit/rollback calls will work.
You could try Spring; it already has transaction managers set up.
Even if you don't use Spring, all you have to do is get XA versions of the JDBC driver JARs in your CLASSPATH. Two phase commit will not work if you don't have them.
I'd wonder if replication using the database would not be a better idea. Why should the middle tier care about database clustering?
Best quick and dirty way for development is to use multiple database connections. They won't be in the same transaction since they are in different connection. I don't think this would be much of an issue if this is just for testing.
When your JTA/XA architecture is ready, just plug it into the already working code.
I need to manage connections to multiple databases in my web app. following are facts regarding the current implementation:
1- I use Tomcat
2- databases are created dynamically at runtime ( i am using mysql)
without a doubt, having a connection pool to manage database connections is optimal.
Since the databases are not known at the start of the application, it was not possible for me to set up datasources and make connection pools. (I could not find a way in Tomcat to make dynamic connection pool: a connection pool that is created at runtime).
my question is: what other options do I have to work efficiently with connections to multiple databases ? (I don't have experience to implement connection pools myself)
is there any library that can be used with tomcat and allow me to establish multiple connection pools to different databases at runtime ? if not what do you suggest that I do instead of connection pools ?
i am fairly new with this issue therefore please correct and guide me if I am messing up concepts.
Thank you in advance.
The MySQL JDBC driver allows omitting the database name from the connection URL as follows:
jdbc:mysql://localhost:3306
You only need to specify the database by Connection#setCatalog() or directly in the SQL queries. See also its reference documentation:
If the database is not specified, the connection will be made with no default database. In this case, you will need to either call the setCatalog() method on the Connection instance or fully specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL. Not specifying the database to use upon connection is generally only useful when building tools that work with multiple databases, such as GUI database managers.
This allows you for creating a single and reuseable connection pooled datasource in Tomcat. You'll perhaps only need to rewrite your connection manager and/or SQL queries.
There are enough connection pooling framework in the open. Proxool is definitely among the best. Its pretty flexible and easy to use.
I'll be using a multi-threaded Java program to insert new records to a table in MySQL. Is it necessary to synchronize for this? Or is it OK since each insert is a different record in my case?
The database driver will do this for you under the covers, if it is necessary. You should assume that the database can handle concurrent CRUD access.
The drivers I've used for SQLServer and Sybase have always locked the Connection object, although you could be using multiple connections via a pool of course!