Options to connect to Oracle8 through tomcat 8.5 - connection-pooling

I am working on a war running on Tomcat 8.5.40, compiled with jdk 8.261 and I need to connect to Oracle with an ojdb8-19.3.0.0 driver. There will be more wars connecting to the same database.
AFAIK and found in the documentation, there are two main ways to implement the connections:
Context/Resource/JNDI (https://tomcat.apache.org/tomcat-8.5-doc/jndi-datasource-examples-howto.html)
Plain Old Java (http://tomcat.apache.org/tomcat-8.5-doc/jdbc-pool.html#Plain_Ol'_Java) (preferred for legacy reasons)
As I am concerned about performance of the connections, I will use Connection Pool.
My question is:
Are both approaches the same in terms of performance?
I just wonder if using Contexts, tomcat manages better the pool, specially when there are multiple wars using it.

There are a couple of disadvantages in configuring datasources in code instead of JNDI:
You introduce a dependency of your code on tomcat-jdbc and a specific version of this library. This means, that your application will work only on specific versions of Tomcat.
You lose the advantages of connection pooling between applications: if you create the datasources programmatically, every application will have its own connection pool. On the other hand, by using JNDI you can decide whether to create one datasource per application or share a global one (see Context versus GlobalNamingResources).
If you use a global datasource the idle connections of your pool are available to all applications, therefore the need to open new TCP/IP connections to the database occurs less often (the cost in time of establishing a new TCP/IP connection is of the order of milliseconds, so relatively high).
GlobalNamingResources example
Configure a data source in server.xml:
<GlobalNamingResources>
<Resource auth="Container"
type="javax.sql.DataSource"
name="jdbc/globalDb"
username="username"
password="secret"
url="jdbc:..." />
...
</GlobalNamingResources>
Add a <ResourceLink> to your context file:
<Context>
<ResourceLink name="jdbc/db"
global="jdbc/globalDb"
type="javax.sql.DataSource" />
...
</Context>

Related

Multiple connection pools on the same database

In my application, I need to configure 2 databases during start up. They are created as Tomcat JDBC pools - org.apache.tomcat.jdbc.pool with seperate pool properties. If I configure such that both the database URLs, user name and password are same i.e., both point to the same database server, then how will be the connection pool created? Will it create 2 pools with different properties or only one? If its only one, which pool properties will be set to the pool - the one which is first created or the next?
Also please suggest if there is any tool which can be used to see the connections to a database and the pools created on it?
My guess is that they would create two separate pools. You can check the SQL server for the "active connections" which the pool should keep a few alive.
My suggestion though, is to use HikariCP as your connection pool. I've found it to be the most robust (survives even if the SQL server goes down) and the fastest (lightest, and smallest lib).

Firedac multiple pools of connections

I'm in process of upgrading our client-server ERP app to multi-tier. We want to offer our customers the possibility having their databases in cloud(hosted in our server).So, clients are written in Delphi, server is a http IOCP server written also in Delphi (from mORMot framework), for dbs we use Firebird embedded.
Our customers(let's say 200), can have 25-30 Firebird databases (total 5000-6000 databases), accessed by 4-5 user per each customer. This is not happening all at once. One user can work in one db, other 2 users can work in another db, but all the dbs should be available and online. So, I can have 800-1000 users working at 700-900 dbs. Databases are not big, typically 20-30 MB each but can go to 200 MB.
This is not data sharding so please don't suggest to merge all databases together, I really need them individually with possibility to backup/restore/replace each one of them.
So, I need multiple pools of connections - for every database I need a pool of let's say 2 connections. I read about Firedac connection pooling. It seems that TFDManager should be perfect for me. I define multiple "ConnectionDef"s with "Pooled=true" and it can maintain multiple pools of connections (each connection lasting until some minutes of inactivity).
Questions:
I have to create all "ConnectionDef"s before server starts serving requests?
Can TFDManager "handle" requests (and time-out connections on inactivity), while in other thread I need to create a new database , so automatically I need to create a new pool of connections and start serving requests from newly created database. Practically can I call FDManager.AddConnectionDef(..) while other pools are in use?
AFAIK Firebird embedded does not have any "connection". As its name states, it is embedded within the same process, so there is no connection pool needed. Connection pools are needed when several clients connect/disconnect to the same DB over the network, whereas here all is embedded, and you would have direct access to the Firebird engine.
As such, you may:
Define one "connnection" per Firebird embedded database;
Protect your SOA code via a mutex (aka critical section) per DB. In fact, mORMot's HTTP IOCP server would run the incoming requests from a thread pool, so ensure that all DB access is safely made.
Ensure you use at least Firebird 2.5 since the embedded version is told to be threadsafe only since revision 2.5 (see the release notes).
Instead of FireDAC, consider using ZDBC/Zeos (in latest 7.2/7.3 branch), which has nice features, together with the native mORMot SynDB libraries.
Looking at Firedac sources, seems that all about adding connection definitions and acquiring connections in pooled mode is thread-safe.
Adding a connection definition or matching one is guarded by a TMultiReadExclusiveWriteSynchronizer and acquiring a connection from the pool is guarded by a TCriticalSection.
So, answers:
I don't have to create all "ConnectionDef"s before server starts serving requests.
Yes, I can call safely FDManager.AddConnectionDef(..) while other pools are in use.
Using Firedac, acquiring a connection for any of those databases will be guarded by one TCriticalSection. The solution proposed by #Arnaud Bouchez presents a more grained access by creating one TCriticalSection per database and I think will scale better, but you should be aware of a bug when using multiple TCriticalSection, especially that all will be initiated at once:
https://www.delphitools.info/2011/11/30/fixing-tcriticalsection/
In that article present a very simple fix for this bug.

JMS Connection Pooling with Websphere MQ 7.0 in Java Standalone application

I'll be developing stand-alone Java application being JMS client. I want to make sure that every time I send a message to a queue, I do not have to create session, connection etc.
I was thinking of using CachedConnectionFactory which comes with Apache Camel or using the solution Spring provides. Still, as far as I know the limitation of the former is that it is not suitable for transactions, and of the latter, that it may not behave correctly in case of failover.
On one post (http://stackoverflow.com/questions/8922339/how-to-pooling-the-jms-connection-in-a-standalone-java-applications) it was suggested to use Apache commons pool component, but I don't think creating such pool would be a trivial task anyway
Any comments on that?

Have additional connections to Derby (read-only)

What I want to do: My application has a full connection to a Derby DB, and I want to poke around in the DB (read-only) in parallel (using a different tool).
I'm not sure how Derby actually works internally, but I understand that I can have only 1 active connection to a Derby DB.
However, since the DB is only consisting of files on my HDD, shouldn't I be able to open additional connections to it, in read-only mode?
Are there any tools to do just that?
There are two possibilities how to run Apache Derby DB.
Embedded: You run DB within your application → only one connection possible
Client: You start DB as server in separate process → classic DB with many connections
You can recognize the type upon driver size. If the driver has more then 2MB that you use embedded version.
Update
When you startup the derby engine (server or embedded) it gets exclusive access to database files.
If you need to access a single database from more than one Java Virtual Machine (JVM), you will need to put a server solution in place. You can allow applications from multiple JVMs that need to access that database to connect to the server.
For details see Double-booting system behavior.
I realize this is an old question, but I thought I might add a little more detail on a solution since links in the currently accepted answer are broken.
It is possible to run the Derby Network Server within a JVM that is using the embedded database already. The code that is using the embedded Derby database doesn't need to change anything and can keep using the DB as is, but with the Derby Network Server started, other programs can connect to derby and access the database.
All you need to do is ensure that derbynet.jar is on the classpath
And then you can do one of the following
Include the following line in the derby.properties file: derby.drda.startNetworkServer=true
Specify the property as a system property at java start
java -Dderby.drda.startNetworkServer=true
You can use the NetworkServerControl API to start the Network Server from a separate thread within a Java application:
NetworkServerControl server = new NetworkServerControl();
server.start (new PrintWriter(System.out));
More details here: http://db.apache.org/derby/docs/10.9/adminguide/tadminconfig814963.html
Keep in mind that doing this does not enable any security on this connection, so it is not a good idea to do this on a production system. It is possible to add security though and that is documented here: http://db.apache.org/derby/docs/10.9/adminguide/cadminnetservsecurity.html
Two other ideas:
In your application, shut down the database and close the connection when the database is not actively in use. Then your application won't interfere with another tool which is trying to open the database.
Make a copy of your database, by taking a backup (you can do this while the database is open by your application), then restore that backup to a separate place on your disk. Then you can use another tool to access the copied database at your ease.
If you can afford the memory and do not need up-to-date data, then you can access read-only databases from multiple JVMs by creating in-memory copies:
ij> connect 'jdbc:derby:memory:memdb;restoreFrom=mydb';

Java: Sharing a connection pool accross other J2SE Apps...?

So I have a connection pool setup. Which is great and all since I have an application that really needs it. However what I would like to know is if it is possible to share this connection pool with other J2SE apps? Would this even be worth it, as opposed to creating a connection pool based on each apps needs? If it would be prudent, how can I accomplish this?
It is not hard having connection pools in a single JVM doing multiple things - that is what applications servers do everyday (using JNDI to throw objects across classloaders)
The interesting part is when you have the connection pool in a separate JVM from the client code needing it, as this does not immediately allow simply asking for and getting a connection from the pool and returning it afterwards.
Basically you have two options:
Doing remote requests for all your JDBC commands over the network. This will most likely mean that the data will travel over the network twice, from the database to the connection pool, and then from the connection pool to your application. If the database connections are very expensive objects then this might be a viable solution.
Use RMI to get the connection object from the connection pool JVM to your own machine. This is a very expensive operation, but can as far as I know include the actual driver classes, allowing your connection pool to provide connections to databases not known to your application JVM. To me this would only make sense if the database connections were ridiculoulusly expensive or it was a requirement to be able to support additional databases after deployment without changing the original deployments.
Note that the primary reason for having connection pools at all is because connections are expensive to create, use shortly and then discard. Some databases more than others, e.g. MySQl is (or was when I tried) very cheap so it might be the simplest just to do that.
So. First of all: Measure what your connection pool buys you in time, and then consider if it is worth your while to centralize this further.

Resources