Some tutorial says use org.postgresql.ds.PGConnectionPoolDataSource but some says just the org.postgresql.ds.PGSimpleDataSource... what is the difference between the two?
The difference is that the class org.postgresql.ds.PGConnectionPoolDataSource implements Connection Pooling, therefore it can provide some performance benefits.
According to the documentation:
Class PGSimpleDataSource
Simple DataSource which does not perform connection pooling. In order
to use the DataSource, you must set the property databaseName. The
settings for serverName, portNumber, user, and password are optional.
Note: these properties are declared in the superclass.
Class PGConnectionPoolDataSource
PostgreSQL implementation of ConnectionPoolDataSource. The app server
or middleware vendor should provide a DataSource implementation that
takes advantage of this ConnectionPoolDataSource. If not, you can use
the PostgreSQL implementation known as PoolingDataSource, but that
should only be used if your server or middleware vendor does not
provide their own. Why? The server may want to reuse the same
Connection across all EJBs requesting a Connection within the same
Transaction, or provide other similar advanced features.
See also:
Connection Pooling with PostgreSQL JDBC
Related
I want to implement a multi-tenant solution where I have one webserver and one database shared across all tenants. Regarding to this blog post from AWS it is "pooled multi tenancy model".
I'm using nest.js and sequelize. If sequelize is not a good fit for this I also could switch to another library like typeORM if necessary.
How can this be implemented? I'm absolutely clueless how I can use a different connection (different database user) for each HTTP request and also I don't know how to set a runtime context variable for the connection in a good way.
What I get currently is that every HTTP requests contains a header tenant-id. This should be used for all queries.
There is also the concept of scopes in sequelize. But this is something that is implemented on the client side and not on the database directly. Also, this is something that is specific to sequelize. I would prefer a solution that is independent from sequelize and maybe more specific to PostgreSQL.
Is there any way to implement this with sequelize? A hint or a basic approach would be sufficient.
That seems that this approach is similar. https://learn.microsoft.com/en-us/microsoft-365/education/deploy/design-multi-tenant-architecture.
I'm studding for create a similar architecture, but i will use the "silo" model or "physical database". I think that at first you need to create a internal database called "catalog" that will contains the information of the user (this user already have a login? if true select this information) where have to contains a previous credentials how tenant-id. About the Sequelize, i guess that is necessary to use RAW queries for create ROLE|GRANT|DATA BASE etc and the MIGRATIONS to create the same DB for each new clients.
Off late, we have been getting hikari connection pools getting exhausted more than a couple of times. The exception being thrown is as follows:
"org.springframework.transaction.CannotCreateTransactionException:
Could not open JDBC Connection for transaction;
nested exception is java.sql.SQLTransientConnectionException:
HikariPool-1 - Connection is not available, request timed out after 30000ms."
What I have observed is that some unaware developers have added #Transactional annotation to a lot of simple get calls on the DB (Postgres).
We use JdbcTemplate to make DB calls with a default connection pool size of 10.
The public endpoints at the controllers are already annotated as #Transactional. Can adding the #Transactional annotation to the DAO Beans result in creation of nested connections when the service layer, which is a seperate bean, which calls the DAO layer is already #Transactional.
We also have a few scheduled CRON jobs, and I see that these are not exposed via a public api or exposed via a controller, but do I still need to add #Transactional to the parent level methods in such cron/internal methods to be able to optimally make db calls? We are not expecting changes to roll back for these cron jobs. We already use JdbcTemplate which uses Hikari Connection poo. Is #Transactional need at all in such cases to optimise performance.
All configurations are default spring boot configurations, so default Tx.Type is REQUIRED unless explicitly set.
#Transactional should be mainly use in service layer when you are about to use database connections, it should be used on minimum methods that represent a business flow.
I think you are over using it and may create unnecessary connections, thus create timeout on overloaded pool
Notice that you use only one database connection pool,as HikariCP, and not also PGBouncer for example.
Also see more performance/configuration tweaks for HikariCP in its wiki page
I am using JPA 2.0 with EclipseLink, Glassfish, and NetBeans. I am experiencing issues with connection timeouts after extended periods of inactivity. I've looked pretty hard for ways to either:
(1) Check for JPA's connection and then re-establish its connection if disconnected
(2) Keep the JPA's connection active as much as possible
However, I can't really find a solution for either. The closest thing I can find is this post: How To modify Eclipselink JPA 2.0 connection retry behavior .
If there is someway to directly work with the JPA's connection, it'd be nice but it's buried within the library.
What you state you are looking for is usually provided by the datasource, in this case it would be configurable in Glassfish as described here:
https://blogs.oracle.com/JagadishPrasath/entry/connection_validation_in_glassfish_jdbc
If you want to do this without a datasource, for instance by passing a URL to the provider and have it handle connections, it will be EclipseLink specific. EclipseLink does have options that can be configured when it attempts to reconnect and retry queries, such as the
public void setPingSQL(String pingSQL)
public void setQueryRetryAttemptCount(int queryRetryAttemptCount)
public void setDelayBetweenConnectionAttempts(int delayBetweenConnectionAttempts)
methods that can be set on the DatabaseLogin or DatabasePlatform classes through a customizer.
using EclipseLink as JPA 2.0 provider, I can obtain a JDBC connection by simply calling
Connection con = entityManager.unwrap(Connection.class);
But I'm unsure what I'm responsible for. Do I have to close the connection after submitting my queries? Or are I'm not allowed to close the connection, because EclipseLink also uses this connection internally. Or does it not care, because EclipseLink observes my behaviour and closes the connection automatically if I don't do it?
If you are in the context of a JPA transaction the connection will be managed by the provider (EclipseLink). If you are outside of a transaction you are responsible for managing the connection yourself.
See the following link for additional information:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/EMAPI#Getting_a_JDBC_Connection_from_an_EntityManager
But I'm unsure what I'm responsible for. Do I have to close the
connection after submitting my queries? Or are I'm not allowed to
close the connection, because EclipseLink also uses this connection
internally.
A good and valid question. It seems that the documentation is lacking the semantics of the unwrap() calls.
Regarding EclipseLink, according from what I got from the source:
EclipseLink gives you a reference to the currently active connection which it uses for the currently active client session transaction. If no transaction is active, a new will be created, associated with the session and returned from the unwrap() method.
As a result, IMHO, a commit/rollback of such a obtained Connection may lead to undefined behavior and/or exceptions. Same is true for executing DML which changed records have been previously cached by eclipselink internal caches or for which managed entities exist.
So when using this API, especially if the underlying transaction is dirty, be careful.
If you can refer to internal eclipselink classes, you can access eclipselink internal connection pool to get a Connection exclusively (have a look at org.eclipse.persistence.sessions.server.ServerSession.getConnectionPool(String) ).
Is it possible to use EJB 3 with JDBC. I read somewhere, that it's allowed.
However, I hear that EJB 3 implementation uses JTA, by default. What does that mean for JDBC? Is it only for the transaction support? That means JTA is used for transaction when using JDBC code? Meaning that even local transactions are implemented as global transactions?
Does it mean it's not a good idea to use JDBC with EJB 3? Many people point me to JPA, but it's an ORM. I want to use SQL.
any suggestions?
1º
That means JTA is used for transaction when using JDBC code ?
And
Meaning that even local transactions are implemented as global transactions ?
The EJB container CAN MAKE USE of resource manager local transactions AS AN OPTIMIZATION TECHNIQUE for enterprise beans for which distributed transactions ARE NOT NEEDED.
It is a good idea do the following when using a declarative or programmatic transaction demarcation:
declare resources using the Resource annotation in the enterprise bean class or using the resource-ref element in the enterprise bean’s deployment descriptor
Something like (setter method or member field)
// mappedName points to a global mapping name
#Resource(mappedName="java:/DefaultDS")
private javax.sql.DataSource ds;
And inside a business logic method
If you are using a declarative transaction
Connection conn = ds.getConnection();
If you are using a programmatic transaction
Declare a setter or member field UserTransaction
#Resource
private UserTransaction ut;
And
ut.beginTransaction();
Connection conn = ds.getConnection();
ut.commit();
Take care of the following
If you are using a Stateful session bean, do the following in the PrePassivate callback method
Close all JDBC connections in the PrePassivate method and assign the instance’s fields storing the connections to null
regards,
You can look at this page, it does appear that you can combine EJB3 with JDBC.
http://www.java2s.com/Tutorial/Java/0415__EJB3/UseJDBCInEJB.htm
If you are using JPA2, you can use entityManager.unwrap(Connection.class) to get actual connection and use with your JDBC code.
For example:
Connection connection = entityManager.unwrap( Connection.class );
try (Statement stmt = connection.createStatement()) {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
}
Does it mean it's not a good idea to use JDBC with EJB 3? Many people
point me to JPA, but it's an ORM. I want to use SQL.
Sometime it's necessary, for performance or compatibility issues. I usually use this technique to execute PL/PSQL with array parameters, complex Posgis SQL, etc.