How to get connection pool size programmatically in JBoss? - java

Is there any way to determine database connection pool size. I want to find out min pool size, max pool size.
The reason is as follows:
My application is running on Wildfly-9.0.1.Final.
I have configure datasource in -ds.xml file.
I have so many clients and for each one there is -ds.xml file.
In each file I have specified max-pool-size = 30.
But for some clients this size(30) happens to be small as more and more user tries to get connection from pool concurrently. Then in that case I need to increase max-pool-size to higher number. I want something like that will help me to fetch these parameters and then based on that I will perform some logic. Like if pool-size have reached to 25/30 then it will trigger email as an alert so that developer can increase its pool size. This way it will be helpful to avoid problems that client do faces when he could not get connection when all are being aquired.
Is there any way to access these connection pool parameters programatically.

Well there are multiple ways. If your datasource would be configured in the standalone.xml you could easily achieve your goal
via the CLI command (have a look here if you're not familiar with the CLI)
/subsystem=datasources/data-source=ExampleDS/statistics=pool:read-resource(include-runtime=true)
through JMX
by reading the following MBean
jboss.as:subsystem=datasources,data-source=ExampleDS,statistics=pool
Beware: In both cases ExampleDS has to be replaced with your actual datasource name.
Update
If you directly drop a -ds.xml into the deployments directory you can read the statistics like this:
/deployment=my-ds.xml/subsystem=datasources/data-source=java\:jboss\/my\/jndiName\/for\/DeployedDS/statistics=pool:read-resource(include-runtime=true)
or
jboss.as:deployment=my-ds.xml,subsystem=datasources,data-source="java:jboss/my/jndiName/for/DeployedDS",statistics=pool
Note that in any case you will have to enable these statistics first before you can acces any useful information with the methods shown above. These statistics might be a performance drawback. You can enable these statistics for example via CLI:
/deployment=my-ds.xml/subsystem=datasources/data-source=java\:jboss\/my\/jndiName\/for\/DeployedDS/statistics=pool:write-attribute(name=statistics-enabled, value=true)
When working with WildFly I'd generally recommend to configure datasources in the standalone.xml - it's way better supported.

Please try this with jboss-cli:
[standalone#localhost:9999 /]
/subsystem=datasources/data-source=ExampleDS/statistics=pool:read-resource(include-runtime=true)

Related

Spring boot - Snowflake JDBC - Alter session automatically when application loads

I'm trying to connect Snowflake to Spring boot based application. Everything works well however due to some crazy defaults in snowflake, I'm having to deal with the below error:
https://community.snowflake.com/s/article/SAP-BW-Java-lang-NoClassDefFoundError-for-Apache-arrow
I can fire the queries via Spring data JPA but not able to map the results at all. The solution asks for changing the default resultset format from ARROW to JSON:
Customer can use this property (jdbc_query_result_format=json) in datasouce property of Application server or session property in application like
Statement = connection.createStatement();
Statement.executeQuery("ALTER SESSION SET JDBC_QUERY_RESULT_FORMAT='JSON'");
I'm just wondering how could I achieve that with Spring ie. run the above SQL in the bootstrap period. I'm using Spring data JPA queries.
The parameter JDBC_QUERY_RESULT_FORMAT can be set per account/user/session, therefore if you always want to have JSON for that user you can set it directly via Snowflake UI only once:
ALTER USER <youruser> SET JDBC_QUERY_RESULT_FORMAT='JSON';
This would only impact your user and the account would still have ARROW as default. And you wouldn't need to set it at session level all the time.
It turns out that the original issue can be fixed easily by tweaking some memory settings in your applications.
Summarising the solution below:
Increase the heap memory and setting -XX:MaxDirectMemorySize > 64M by setting the JAVA_OPTS property for your application.
The rationale behind this is that Arrow format inherently make use of the available heap memory in order to optimise the large results. Not having enough heap space will lead to the above mentioned error.
I still need to perform more tests to find out the ideal values for heap memory, stack size, and this variable → -XX:MaxDirectMemorySize.
EDIT: Below settings worked:
"JAVA_OPTS": "-Xss230k -XX:ReservedCodeCacheSize=100m -Xmx1800m -XX:MaxDirectMemorySize=1500m"
6 instances of the app running in parallel.
2GB RAM per instance ie. 12GB RAM in total (probably an overkill but it snowflake driver does eat up a lot of ram in general)

how to get the size of hibernate connection pool?

I have an app that is written in java spring.
It uses hibernate to handle connections to postgres DB.
I want to get the size of the connection pool, but it isn't defined on the app's hibernate configurations.
So I guess it uses hibernate default size, which is 1?
That sounds very low to me.
How can I be sure what is the size of connection pool?
I read that it is recommended to use third party manager for this, but I don't think it's in used also.

How to set wait Queue Multiple and Max Pool Size in application.properties for MongoDB

Recently move from local storage to a database located in linode. I'm moving all the projects there and now i have to use authentication for mongo Database. I used to use uri configuration:
spring.data.mongodb.uri=mongodb://localhost/testDatabase?waitQueueMultiple=500&maxPoolSize=1000
In the uri i set 500 as Wait Queue Value and 1000 as Max Pool Size
Now Im using another config due to security:
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
spring.data.mongodb.database=testDatabase
spring.data.mongodb.username=root
spring.data.mongodb.password=MySuperPassword
Exist any field where i can set wait queue an pool size values?
or
Can i set security config in the uri ?
Thanks for your help.
You can set both user/password and extra properties in spring.data.mongodb.uri
spring.data.mongodb.authentication-database needs a separate property.
See Connecting to a MongoDB Database (it gives an example of replica set, but the principles still apply for the properties you want)
You can set the spring.data.mongodb.uri property to change the URL and configure additional settings such as the replica set, as shown in the following example:
spring.data.mongodb.uri=mongodb://user:secret#mongo1.example.com:12345,mongo2.example.com:23456/test
If you use the Mongo 3.0 Java driver, spring.data.mongodb.host and spring.data.mongodb.port are not supported. In such cases, spring.data.mongodb.uri should be used to provide all of the configuration.
see also https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Maybe its a long time after asking the question but finally found the correct way to set this properties, hope this helps to someone with the same question :D
mongodb://user:password#ip:port/databaseName?authSource=admin&waitQueueMultiple=1000&maxPoolSize=1000

Connection pool for dynamic database connections

The problem setup is based on a webservice (Spring/Java, Tomcat7 and MySql) where every user gets their own database, hence each request needs their own connection. As all databases are created dynamically during runtime, configuring them statically before startup is not an option.
To optimise database connection usage, an implementation of a database connection pool would be great, right?
With Java/Spring: How would I create a connection pool for dynamic databases? I am a bit struck by the lack of clean options here!
Problem: Tomcat's Connection Pool (and as far as i understand C3P0 as well) treats each new DataSource instance as a whole new connection pool -> stack-reference
Is it a good idea to create a static datasource with a generic MySql connection (without specifing the database on connection) and use a connection pool with this datasource together with adapted SQL statements?
stack-reference
What about developing a custom persistent database based datasource pool? Any experience with performance here? Any advice? Any libraries that do that?
Or would it be feasable to workaround Tomcat's DataSource problem by creating Tomcat JNDI Datasources dynamically by manipulating it's context.xml dynamically from Java?
I can't believe that there aren't more plain/simple solutions for this. Grails/Hibernate struggles with this, Java/JDBC struggles with this, ... is it such a rare use-case to separate userdata on a user basis by creating user specific databases dynamically? If so, what would be a better setup?
EDIT
Another option is the suggestion from #M.Deinum to use a single configured datasource and dynamically hotswap it for the right connection ->M.Deinum Blog and stack-reference. How does that perform with a connection pool like the ones above?
I believe that HikariCP works without having to specify a single database.
Once the databases are created in runtime, you have to create the pools also in runtime. I am afraid the spring infrastructure is not giving you any help here, as it is tuned for the usual static use case.
I'd have a map of pools:
have a Map < connectionUrlString,List< c3poPool > > map
when requesting a connection, get the corresponding c3po pool from the map
and you can get the best of both worlds, since the real connection pool for each dynamically created database is handled by a c3po instance, but you can create new instances in runtime
This works as a low-level solution. If you want to go further, you can wrap this logic into a db connection provider, and register that as a "driver". This way any part of your application requests a new connection, you can just return one connection from the existing pools (and if a totally new connection is requested, create a new pool for that).
First than all, sorry for my english, i'm improving every day.
In my experience, I had a similar situation and it was resolve with spring framework. Let me explain you how you'd solve that question.
Make a spring config file with these characteristics:
a) A resource loader: This one is the responsible of load properties from configurations files or from database, those properties will be the appropriates to establish the database connection.
b) A pool database configuration parameterized with the properties that you'll load.
Create a locator class: In this class you'll need a HashMap
Use the multi context feature of spring: The idea is assign a code to every one connection that you establish and later load that connection like an application context with spring, then in the locator class, put in the map that context and use it as frequent as you need.
I think is you follow these steps, you can create dynamic pool or database connection as you want.

Context specific usernames for connections on a Java EE Datasource (JBoss 5.1)

We have an application that needs to access a database that is owned by a different team.
That database has security inside the database (triggers, table permissions, etc) and so we need to establish a connection to the database using the same username/password that connected to our EJB.
We're running on JBoss 5.1. Standard Java EE solutions are preferred, but JBoss specific answers will do.
At the moment our solution is
Create a datasource in JBoss with no user-id password
Require the client to pass their username/password into the EJB (the EJB is a stateful session bean (SFSB), and remembers the username/password)
The session bean creates a new connection using DataSource.getConnection(String, String)
The connection is "created" from the datasource at the start of each request (The datasource implementation might reuse an existing connection)
The main problem we have is connection pooling.
The JBoss connection pool doesn't manage separate pools for each username - they're all thrown into 1 big pool, and the username is checked after the object is retrieved from the pool (inside InternalManagedConnectionPool).
If the usernames don't match, then the connection is removed from the pool & destroyed.
This means that as soon as we have 2 users, there's a 50% chance that any connection that is put into the pool will be destroyed when it is next accessed. And as we increase the number of users, those odds get a lot worse.
We can't simply create 1 connection in the SFSB and retain it because JBoss is too smart for us, and it detects that we've left a connection open and automatically returns it to the pool for us, so the next request to the SFSB will fail with a "not associated" connection.
It would also be nice if we could simply get JBoss to create a connection as "the currently logged in user", but the solution we have is bearable.
My googling has failed to find any recommended patterns for doing this sort of thing. Everyone seems to assume that you want your datasource to use a single user for all connections (which is nice when it's possible, but I can't do that in this case)
The only solutions I can some up with are
Don't use a container provided datasource. Put the JDBC URL into a configuration value somewhere and create connections myself (possibly with the help of spring)
Bind a different Datasource implementation (possibly a custom one) into JNDI
Has anyone got any better solutions? Or pointers to recommended practices in this area?
(The database is Sybase ASE 15, but I doubt that makes any difference to the solution)
A bit more reading of the documentation has led me to what appears to be the solution.
Adding
<application-managed-security/>
into my datasource file seems to have fixed the problem of pooling the connections.
I'm not sure how I missed that the first time around.

Categories