Analyzing the performance of SQL queries between OnPrem and AWS environment - java

I am working in modernizing an existing REST services and moving from OnPrem to AWS.
The legacy application
deployed in a OnPrem Liberty Server
MS SQL server DB was used.
Spring/Hibernate was the core technologies.
New Application Details :
Spring Boot deployed in the AWS environment in a docker container
Server-Tomcat embedded with the Spring boot.
Database is the existing MS Sql server and it is located OnPrem
Some queries which were earlier took less that 500ms to execute is now taking upto 2000ms. The queries,logic and other code related thigs are same between the legacy and the new application. We are not able to find why the queries are taking more time in this.
In the legacy application we had used the server.xml to configure the data source and in the new application we have configured the data source in the Spring boot application.properties . Below are the Datasource configurations:
Liberty Server datasource :
<dataSource id="Microsoft SQL Server JDBC Driver - DataSource - JVM3" jndiName="jdbc/xxx" containerAuthDataRef="yyy" statementCacheSize="50" isolationLevel="TRANSACTION_READ_COMMITTED">
<jdbcDriver libraryRef="MSSQLJDBCLib"/>
<properties.microsoft.sqlserver databaseName="dbName" serverName="servername.com" portNumber="9999" lockTimeout="2000" packetSize="4096" sendStringParametersAsUnicode="false" trustStorePassword="{xor}" beginTranForVendorAPIs="false" freeResourcesOnClose="false" jmsOnePhaseOptimization="false" reauthentication="false" preTestSQLString="SELECT 1" validateNewConnection="false" validateNewConnectionRetryInterval="3" errorDetectionModel="ExceptionMapping" nonTransactionalDataSource="false" name="Microsoft SQL Server JDBC Driver - DataSource - JVM3" enableMultithreadedAccessDetection="false" beginTranForResultSetScrollingAPIs="false" validateNewConnectionRetryCount="100" connectionSharing="1"/>
<connectionManager agedTimeout="-1" connectionTimeout="180" maxIdleTime="300" maxPoolSize="30" minPoolSize="0" reapTime="240" purgePolicy="FailingConnectionOnly"/>
</dataSource>
Spring Boot Datasource :
spring.datasource.url=jdbc:sqlserver://server.com:9999;databaseName=dBName
spring.datasource.hikari.maximumPoolSize=30
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=180000
What may be the other parameters which can impact the query performance between the old and the new application?
Note : The ping time between the AWS servers and the OnPrem db takes less than 2ms (very negligible).

The issue is fixed. All the queries which we made to the database were doing an Index scan instead of index seek. That is because we missed the sendStringParametersAsUnicode="false" parameter in the Connection JDBC url.
We changed the connection url to take the required parameters and the queries ran perfectly fine.
spring.datasource.url=jdbc:sqlserver://server.com:9999;databaseName=dBName;packetSize=4096;sendStringParametersAsUnicode=false

Related

How to keep database active in spring boot application

We are using spring boot, apache camel and multiple datasources.
spring boot version: 1.5.9 release
primary database: postgres
Secondary database:oracle
We have deployed spring boot jar in linux server.
Datasource properties for postgres is
x.datasource.url=
x.datasource.username=
x.datasource.password=
x.data.jpa.repositories.enabled=true
datasource properties for oracle
y.datasource.url=
y.datasource.username=
y.datasource.password=
y.data.jpa.repositories.enabled=true
when application keeps ideal and After some times we are trying first request failed and getting error jdbc connection failed but it is working in second request without restarting.
please let me know how to keep database active.
You can use hikari connection pool. Refer to this on how to implement. You can configure no. of connections you want to keep with db

How to get real path of my file?

I'm working on a web application using netbeans and MS Acces as my database, in my connection class I tried to get the path of my acces file (located inside my project) via the following command:
File f = new File("softTech.accdb");
String path = f.getAbsolutePath();
The problem is, as soon as I run the project and it tries to connect, when trying to get the path, the system gives me a path inside the tomcat's paste
I need your help, don't know what to do
Thanks in advance
There are two points:
First: MS Access is really the worst choice as a database for a Java web application.
MS Access is a desktop database not made for using it at the server side.
The JDBC-ODBC bridge was never meant for production use and was removed in Java 8.
The alternate driver Ucanaccess is nice for data exchange scenarios with a MS Access database but it uses a pure Java database (HSQLDB) as a buffer and an emulation layer to avoid the use of the original Jet Engine. This alone is a performance nightmare.
So you should consider to use another database for your web application. There are plenty of alternatives like SQLite, Apache Derby or H2 as embedded database engines or MySQL, PostgreSQL as client-server database systems. All with dedicated JDBC driver support.
Second: The database path or the connection shouldn't be hardcoded inside your web application. You should configure a named datasource in your application server (e.g. Tomcat). And inside your web application you can access the datasource via JNDI.
Example: Configure the database connection factory in Tomcat:
<Context ...>
...
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
...
</Context>
Example: Access the datasource via JNDI:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
The examples are part of the Tomcat documentation.
The benifit is, the web application only knows the logical database name. You can have multiple Tomcat installation, e.g. one for testing with a test database and one production. You can use the same WAR file for both installations. Each Tomcat has to be configured only once.
If you are using servlets then following code should work.
getServletContext().getRealPath("/yourFileName")
In case of normal java class, you can use
new File("yourFileName").getCanonicalPath();

Sharing database connection pool between Spring Boot apps running Embedded Tomcat

My current production setup requires me to share Oracle database connection pools between multiple Spring Boot apps where each app runs via an embedded Tomcat instance.
What options do I have to share the database connection pool among these Spring Boot apps?
Is JNDI an option? If so, could someone explain how storing the connection pool details in say LDAP accessed via JNDI works?

Spring MVC application getting hung on server start up

I am trying to deploy my spring + Hibernate application on JBOSS. while i am starting the server, server start is getting hung. Last entry in the start up log is -
DEBUG: org.springframework.jdbc.datasource.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [myDatabaseURL]
In my application there are around 80 hibernate mapping file. when I am removing all of them excluding one simple basic mapping file, application is able to connect to the DB.
I also try to connect to DB using PLSQL developer and I was able to connect. So in other words DB is working fine.
Any suggestion or pointer for debug ? What can be possible reasons which i am overlooking?
Thanks

How do I use JDBC's data source?

I've tried researching how to use the DataSource method of connecting to a database but never could find out how. I know that a DataSource is first configured and registered to JNDI in an application that is separate from the user application, and all the user application will do is retrieve it using JNDI. What I don't understand is where the DataSource is configured. Is it automatically registered when I turn on MySQL, do I need to download another application to register it, or do I make a new class that will do that for me?
You usually have a Java EE app server like Glassfish, WebLogic, JBOSS, Tomcat, or Jetty have a JNDI provider that you should be using for the lookup.
Here's how you do it with Oracle.
Here's how you do it with MySQL.
The JDK 6 javadocs say that a basic DataSource can supply a connection if your driver has such an implementation. I would recommend looking at the Connector-J docs to see if you can do it without JNDI lookup services.

Categories

Resources