{"id":142,"date":"2020-06-04T00:12:12","date_gmt":"2020-06-04T07:12:12","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=142"},"modified":"2020-06-29T02:34:48","modified_gmt":"2020-06-29T09:34:48","slug":"improve-jdbc-application-reliability-with-azure-sql-and-connection-pooling","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/improve-jdbc-application-reliability-with-azure-sql-and-connection-pooling\/","title":{"rendered":"Improve JDBC application reliability with Azure SQL and connection pooling"},"content":{"rendered":"<h2 aria-level=\"2\"><span data-contrast=\"none\">Introduction<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">A growing number of<\/span><span data-contrast=\"auto\">\u00a0Azure SQL Database<\/span><span data-contrast=\"auto\">\u00a0customers are developin<\/span><span data-contrast=\"auto\">g new applications in Java<\/span><span data-contrast=\"auto\">, or porting existing ones, using a JDBC driver from Microsoft or a 3<\/span><span data-contrast=\"auto\">rd<\/span><span data-contrast=\"auto\">\u00a0party.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">While\u00a0<\/span><span data-contrast=\"auto\">these drivers are\u00a0<\/span><span data-contrast=\"auto\">providing quite extensive support\u00a0<\/span><span data-contrast=\"auto\">and\u00a0<\/span><span data-contrast=\"auto\">covering most of database service capabilities and performance expectations,\u00a0<\/span><span data-contrast=\"auto\">there are a couple of areas that worth\u00a0<\/span><span data-contrast=\"auto\">some\u00a0<\/span><span data-contrast=\"auto\">special\u00a0<\/span><span data-contrast=\"auto\">attention<\/span><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">An important distinction<\/span><span data-contrast=\"auto\">\u00a0in cloud environments<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">compared to<\/span><span data-contrast=\"auto\">\u00a0traditional on-premises enterprise\u00a0<\/span><span data-contrast=\"auto\">solutions<\/span><span data-contrast=\"auto\">\u00a0is that network interruptions between application\u00a0<\/span><span data-contrast=\"auto\">tier and database service can happen more frequently, due for example to\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/sql-database\/sql-database-planned-maintenance\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">planned<\/span><\/a><span data-contrast=\"auto\">\u00a0maintenance activities,\u00a0<\/span><span data-contrast=\"auto\">unplanned failures or\u00a0<\/span><span data-contrast=\"auto\">other network connectivity\u00a0<\/span><span data-contrast=\"auto\">glitches<\/span><span data-contrast=\"auto\">.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">As explained in th<\/span><span data-contrast=\"auto\">at document, these interruptions are generally self-resolved in few seconds from a service perspective,\u00a0<\/span><span data-contrast=\"auto\">and applications with\u00a0<\/span><span data-contrast=\"auto\">proper\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/sql-database\/sql-database-connectivity-issues#retry-logic-for-transient-errors\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">retry logic<\/span><\/a><span data-contrast=\"auto\">\u00a0in place are\u00a0<\/span><span data-contrast=\"auto\">usually not even affected.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Some\u00a0<\/span><span data-contrast=\"auto\">client libraries like\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/sql-database\/sql-database-connectivity-issues#net-sqlconnection-parameters-for-connection-retry\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">SqlClient<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/connect\/odbc\/windows\/connection-resiliency-in-the-windows-odbc-driver?view=sql-server-2017\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">ODBC<\/span><\/a><span data-contrast=\"auto\">\u00a0driver<\/span><span data-contrast=\"auto\">\u00a0or\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/ef\/ef6\/fundamentals\/connection-resiliency\/retry-logic\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">EntityFramework<\/span><\/a><span data-contrast=\"auto\">\u00a0are even providing some\u00a0<\/span><span data-contrast=\"auto\">embedded\u00a0<\/span><span data-contrast=\"auto\">connection retry capabilities<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">and<\/span><span data-contrast=\"auto\">\u00a0customers can simply configure through connection strings without<\/span><span data-contrast=\"auto\">\u00a0modifying application code<\/span><span data-contrast=\"auto\">.\u00a0<\/span><span data-contrast=\"auto\">These will usually help in deal with\u00a0<\/span><span data-contrast=\"auto\">transient issues happening when connections are sitting idle in connection pools<\/span><span data-contrast=\"auto\">, making sure that pure application logic will remain unchanged.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"2\"><span data-contrast=\"none\">Retry logic frameworks<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">A more sophisticated use case is when these transient errors are happening while the application is\u00a0<\/span><span data-contrast=\"auto\">actually executing<\/span><span data-contrast=\"auto\">\u00a0some command against the database.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">For this<\/span><span data-contrast=\"auto\">\u00a0scenario<\/span><span data-contrast=\"auto\">,\u00a0<\/span><span data-contrast=\"auto\">command retry strategies that can be defined in your code to<\/span><span data-contrast=\"auto\">\u00a0repeat failed commands after a fixed or exponential time interval<\/span><span data-contrast=\"auto\">, letting developers to implement proper logic to avoid duplicate executions and potential inconsistent state<\/span><span data-contrast=\"auto\">\u00a0in the database<\/span><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">As of today<\/span><span data-contrast=\"auto\">, unfortunately,\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/connect\/jdbc\/microsoft-jdbc-driver-for-sql-server?view=sql-server-2017\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Microsoft JDBC Driver<\/span><span data-contrast=\"none\">\u00a0for SQL Server<\/span><\/a><span data-contrast=\"auto\">\u00a0doesn\u2019t provide\u00a0<\/span><span data-contrast=\"auto\">idle connection\u00a0<\/span><span data-contrast=\"auto\">retry<\/span><span data-contrast=\"auto\">\u00a0capabilities<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">mainly\u00a0<\/span><span data-contrast=\"auto\">because\u00a0<\/span><span data-contrast=\"auto\">some\u00a0<\/span><span data-contrast=\"auto\">challenges residing<\/span><span data-contrast=\"auto\">\u00a0in\u00a0<\/span><span data-contrast=\"auto\">underlying Java classes responsible for managing TCP sockets<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">are preventing a reliable and performant way of detecting network interruptions\u00a0<\/span><span data-contrast=\"auto\">without executing a roundtrip with the server which would introduce performance overhead.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0of course<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0doesn\u2019t\u00a0<\/span><span data-contrast=\"auto\">necessarily reduce the possibilities of creating reliable and efficient Java apps working with Azure SQL Database but<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0rather<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\">\u00a0tha<\/span><span data-contrast=\"auto\">t<\/span><span data-contrast=\"auto\">\u00a0some\u00a0<\/span><span data-contrast=\"auto\">attentions from application developers are needed to prevent\u00a0<\/span><span data-contrast=\"auto\">potential issues in some circumstances.<\/span><span data-contrast=\"auto\">\u00a0For example, in the Java<\/span><span data-contrast=\"auto\">-sphere, a number of frameworks exists that can be used to define<\/span><span data-contrast=\"auto\">\u00a0sophisticated<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">retry logic strategies to detect transient errors and repeat specific operations or entire code blocks.\u00a0<\/span><span data-contrast=\"auto\">Some examples are\u00a0<\/span><a href=\"https:\/\/github.com\/elennick\/retry4j\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Retry4j<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><a href=\"https:\/\/github.com\/jhalterman\/failsafe\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">FailSafe<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><span data-contrast=\"auto\">and even\u00a0<\/span><a href=\"https:\/\/github.com\/spring-projects\/spring-retry\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Spring-retry<\/span><\/a><span data-contrast=\"auto\">, all quite straightforward to use<\/span><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"2\"><span data-contrast=\"none\">Importance of d<\/span><span data-contrast=\"none\">efault connection properties<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/connect\/jdbc\/setting-the-connection-properties?view=sql-server-2017\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Connection properties<\/span><\/a><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">are playing an important role on how\u00a0<\/span><span data-contrast=\"auto\">interaction between applications and backend database services will behave.<\/span><span data-contrast=\"auto\">\u00a0These can be specified as part of\u00a0<\/span><span data-contrast=\"auto\">the connection string, or\u00a0<\/span><span data-contrast=\"auto\">through specific methods of\u00a0<\/span><span data-contrast=\"auto\">DriverManager<\/span><span data-contrast=\"auto\">\u00a0or\u00a0<\/span><span data-contrast=\"auto\">DataSource<\/span><span data-contrast=\"auto\">\u00a0classes in application code<\/span><span data-contrast=\"auto\">, and s<\/span><span data-contrast=\"auto\">ome of these properties are\u00a0<\/span><span data-contrast=\"auto\">more<\/span><span data-contrast=\"auto\">\u00a0relevant<\/span><span data-contrast=\"auto\">\u00a0than others<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">in<\/span><span data-contrast=\"auto\">\u00a0mak<\/span><span data-contrast=\"auto\">ing<\/span><span data-contrast=\"auto\">\u00a0sure that application can manage transient\u00a0<\/span><span data-contrast=\"auto\">conditions properly.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><i><span data-contrast=\"auto\">loginTimeout<\/span><\/i><i><span data-contrast=\"auto\">\u00a0<\/span><\/i><span data-contrast=\"auto\">defines t<\/span><span data-contrast=\"auto\">he number of seconds the driver should wait before timing out a failed connection.\u00a0<\/span><span data-contrast=\"auto\">If we don\u2019t specify it,\u00a0<\/span><span data-contrast=\"auto\">timeout\u00a0<\/span><span data-contrast=\"auto\">will be<\/span><span data-contrast=\"auto\">\u00a0the default system timeout, which is 15\u00a0<\/span><span data-contrast=\"auto\">seconds.\u00a0<\/span><span data-contrast=\"auto\">In most cases, this\u00a0<\/span><span data-contrast=\"auto\">alone will cover a transient connection blip due to a reconfiguration\u00a0<\/span><span data-contrast=\"auto\">or a failover, and the application will just experience a\u00a0<\/span><span data-contrast=\"auto\">relatively\u00a0<\/span><span data-contrast=\"auto\">short delay.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">If<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">interruptions are longer,\u00a0<\/span><span data-contrast=\"auto\">in general just increasing the timeout\u00a0<\/span><span data-contrast=\"auto\">may or may not be a good idea, and that depends a lot on\u00a0<\/span><span data-contrast=\"auto\">specific workload characteristics. For interactive workloads,<\/span><span data-contrast=\"auto\">\u00a0for example,<\/span><span data-contrast=\"auto\">\u00a0usually\u00a0<\/span><span data-contrast=\"auto\">keeping timeout relatively low, report the issue to the end user and eventually ask to retry the operation\u00a0<\/span><span data-contrast=\"auto\">is a good approach.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">Even for batch approaches can be valuable to just<\/span><span data-contrast=\"auto\">\u00a0catch the exception due to a transient issue,\u00a0<\/span><span data-contrast=\"auto\">log it somewhere and retry, rather than just let the application hang for longer time.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><i><span data-contrast=\"auto\">queryTimeout<\/span><\/i><i><span data-contrast=\"auto\">\u00a0<\/span><\/i><span data-contrast=\"auto\">and\u00a0<\/span><i><span data-contrast=\"auto\">socketTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0instead are more relevant for<\/span><span data-contrast=\"auto\">\u00a0service interruptions that may happen\u00a0<\/span><span data-contrast=\"auto\">while<\/span><span data-contrast=\"auto\">\u00a0a command<\/span><span data-contrast=\"auto\">\u00a0is<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">getting executed<\/span><span data-contrast=\"auto\">\u00a0or is returning results to the client<\/span><span data-contrast=\"auto\">.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">B<\/span><span data-contrast=\"auto\">ehind the scenes,\u00a0<\/span><span data-contrast=\"auto\">when\u00a0<\/span><span data-contrast=\"auto\">JDBC driver<\/span><span data-contrast=\"auto\">\u00a0is<\/span><span data-contrast=\"auto\">\u00a0executing a command and waiting for a response from the server, it<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">uses\u00a0<\/span><a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/io\/InputStream.html#read(byte%5B%5D,%20int,%20int)\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Read<\/span><\/a><span data-contrast=\"auto\">() method<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">Java\u2019s\u00a0<\/span><span data-contrast=\"auto\">InputStream<\/span><span data-contrast=\"auto\">\u00a0class,\u00a0<\/span><span data-contrast=\"auto\">and\u00a0<\/span><span data-contrast=\"auto\">the method blocks until the requested number of bytes return.\u00a0<\/span><span data-contrast=\"auto\">TCP is a synchronous communication scheme that requires &#8220;handshaking&#8221; from both sides of the connection as packets are exchanged (SYN and ACK packets).<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">If the data flow is interrupted\u00a0<\/span><span data-contrast=\"auto\">abruptly\u00a0<\/span><span data-contrast=\"auto\">due to connectivity issues the application effectively hangs<\/span><span data-contrast=\"auto\">, and even if connection will get re-established,\u00a0<\/span><span data-contrast=\"auto\">application will stay in that state until it will get restarted.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">As explained in this\u00a0<\/span><span data-contrast=\"auto\">quite\u00a0<\/span><span data-contrast=\"auto\">extensive\u00a0<\/span><a href=\"https:\/\/www.cubrid.org\/blog\/3826470\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">article<\/span><\/a><span data-contrast=\"auto\">\u00a0on this subject, r<\/span><span data-contrast=\"auto\">ole of\u00a0<\/span><span data-contrast=\"auto\">timeouts\u00a0<\/span><span data-contrast=\"auto\">is to deal with statement<\/span><span data-contrast=\"auto\">\u00a0executions that are taking longer than expected, but also to deal with so called \u201cdead connections\u201d to wait indefinitely\u00a0<\/span><span data-contrast=\"auto\">and impact application availability.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This is because both timeouts by default are set to -1, which means\u00a0<\/span><span data-contrast=\"auto\">that\u00a0<\/span><span data-contrast=\"auto\">t<\/span><span data-contrast=\"auto\">he application will wait forever<\/span><span data-contrast=\"auto\">\u00a0and not react to what will happen on the service side.<\/span><span data-contrast=\"auto\">\u00a0So, why those values are not set to meaningful numbers by default in the JDBC driver?<\/span><span data-contrast=\"auto\">\u00a0The answer is that safe values will depend again a lot on specific workloads, so a best practice is actually that\u00a0<\/span><span data-contrast=\"auto\">developers and system engineers will set them based\u00a0<\/span><span data-contrast=\"auto\">on what \u201cregular\u201d and expected\u00a0<\/span><span data-contrast=\"auto\">query execution times will be.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">If\u00a0<\/span><span data-contrast=\"auto\">max execution time under regular conditions is<\/span><span data-contrast=\"auto\">, let\u2019s say, 2 seconds\u00a0<\/span><span data-contrast=\"auto\">a reasonable\u00a0<\/span><i><span data-contrast=\"auto\">queryTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0could be<\/span><span data-contrast=\"auto\">\u00a0for example 15 seconds (to make sure\u00a0<\/span><span data-contrast=\"auto\">we cover temporarily slow query execution times without necessarily failing) whole<\/span><span data-contrast=\"auto\">\u00a0an healthy<\/span><span data-contrast=\"auto\">\u00a0<\/span><i><span data-contrast=\"auto\">socketTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">could be 30 seconds<\/span><span data-contrast=\"auto\">\u00a0so that, worst case, the application will be able to<\/span><span data-contrast=\"auto\">\u00a0react to the exception and apply proper retry logic as previously described.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"2\"><span data-contrast=\"none\">Connection pooling<\/span><span data-contrast=\"none\">\u00a0libraries<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">Connection pooling<\/span><span data-contrast=\"auto\">\u00a0is a technique to\u00a0<\/span><span data-contrast=\"auto\">maintain a cache of idle database connections that can be\u00a0<\/span><span data-contrast=\"auto\">reused for future requests to mitigate the cost of\u00a0<\/span><span data-contrast=\"auto\">opening new connections and manage resources efficiently.<\/span><span data-contrast=\"auto\">\u00a0In\u00a0<\/span><span data-contrast=\"auto\">client libraries like\u00a0<\/span><span data-contrast=\"auto\">SqlClient<\/span><span data-contrast=\"auto\">\u00a0or ODBC<\/span><span data-contrast=\"auto\">, connection pooling capabilities are natively implemented, while generally JDBC drivers are\u00a0<\/span><span data-contrast=\"auto\">just implementing required interfaces for\u00a0<\/span><span data-contrast=\"auto\">3<\/span><span data-contrast=\"auto\">rd<\/span><span data-contrast=\"auto\">\u00a0party components<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">to provide these capabilities.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">Historically speaking, s<\/span><span data-contrast=\"auto\">ome\u00a0<\/span><span data-contrast=\"auto\">of these\u00a0<\/span><span data-contrast=\"auto\">libraries<\/span><span data-contrast=\"auto\">\u00a0like\u00a0<\/span><a href=\"http:\/\/brettwooldridge.github.io\/HikariCP\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">HikariCP<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><a href=\"https:\/\/www.mchange.com\/projects\/c3p0\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">C3P0<\/span><\/a><span data-contrast=\"auto\">,\u00a0<\/span><a href=\"https:\/\/commons.apache.org\/proper\/commons-dbcp\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Dbcp2<\/span><\/a><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">or<\/span><span data-contrast=\"auto\">\u00a0<\/span><a href=\"http:\/\/www.vibur.org\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">Vibur<\/span><\/a><span data-contrast=\"auto\">\u00a0emerged\u00a0<\/span><span data-contrast=\"auto\">as\u00a0<\/span><span data-contrast=\"auto\">widely used within Java development community.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">For\u00a0<\/span><span data-contrast=\"auto\">the reasons\u00a0<\/span><span data-contrast=\"auto\">mentioned above,\u00a0<\/span><span data-contrast=\"auto\">connection pooling\u00a0<\/span><span data-contrast=\"auto\">can play a role\u00a0<\/span><span data-contrast=\"auto\">in overall application reliability<\/span><span data-contrast=\"auto\">.\u00a0<\/span><span data-contrast=\"auto\">They all offer an implicit<\/span><span data-contrast=\"auto\">\u00a0(e.g. supporting JDBC4\u00a0<\/span><span data-contrast=\"auto\">Connection.isValid<\/span><span data-contrast=\"auto\">() method)<\/span><span data-contrast=\"auto\">\u00a0or explicit\u00a0<\/span><span data-contrast=\"auto\">way of<\/span><span data-contrast=\"auto\">\u00a0specify a test query to<\/span><span data-contrast=\"auto\">\u00a0valid<\/span><span data-contrast=\"auto\">ate<\/span><span data-contrast=\"auto\">\u00a0connections\u00a0<\/span><span data-contrast=\"auto\">when\u00a0<\/span><span data-contrast=\"auto\">application is requesting them, or to setup idle timeout to\u00a0<\/span><span data-contrast=\"auto\">evict connections from the pool after a given timeout when they are not used.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">HikariCP<\/span><span data-contrast=\"auto\"> is <\/span><a href=\"https:\/\/github.com\/brettwooldridge\/HikariCP\/wiki\/Bad-Behavior:-Handling-Database-Down\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">battle-tested<\/span><\/a><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">on\u00a0<\/span><span data-contrast=\"auto\">transient<\/span><span data-contrast=\"auto\">\u00a0connectivity errors, but it is important to re-iterate the importance of\u00a0<\/span><span data-contrast=\"auto\">proper configur<\/span><span data-contrast=\"auto\">ation\u00a0<\/span><span data-contrast=\"auto\">on both connection pooling\u00a0<\/span><a href=\"https:\/\/github.com\/brettwooldridge\/HikariCP#configuration-knobs-baby\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">layer<\/span><\/a><span data-contrast=\"auto\">\u00a0and on\u00a0<\/span><span data-contrast=\"auto\">specific JDBC driver connection properties like the\u00a0<\/span><i><span data-contrast=\"auto\">socketTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0emphasized earlier.<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">This one remain critical to signal to the connection pooling infrastructure that the\u00a0<\/span><span data-contrast=\"auto\">underlying connection with database is not responding properly and then it should eliminated from the pool<\/span><span data-contrast=\"auto\">\u00a0instead of remaining there forever in a stuck state.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">On<\/span><span data-contrast=\"auto\">\u00a0connection pooling<\/span><span data-contrast=\"auto\">\u00a0specifics<\/span><span data-contrast=\"auto\">, in addition to obvious\u00a0<\/span><span data-contrast=\"auto\">properties determining pool size (<\/span><i><span data-contrast=\"auto\">minumumIdle<\/span><\/i><span data-contrast=\"auto\">\u00a0and\u00a0<\/span><i><span data-contrast=\"auto\">maximumPoolSize<\/span><\/i><span data-contrast=\"auto\">, default 10 each but likely dependent on\u00a0<\/span><span data-contrast=\"auto\">specific workload<\/span><span data-contrast=\"auto\">)<\/span><span data-contrast=\"auto\">, there are\u00a0<\/span><span data-contrast=\"auto\">some additional<\/span><span data-contrast=\"auto\">\u00a0properties that should be carefully considered<\/span><span data-contrast=\"auto\">\u00a0for application availability.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><i><span data-contrast=\"auto\">connectionTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0controls the amount of time that the app will wait for getting a connection from the pool.\u00a0<\/span><span data-contrast=\"auto\">Default is 30 sec<\/span><span data-contrast=\"auto\">,\u00a0<\/span><span data-contrast=\"auto\">and it makes sense to keep it slightly higher than<\/span><span data-contrast=\"auto\">\u00a0JDBC driver\u00a0<\/span><i><span data-contrast=\"auto\">loginTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0in case\u00a0<\/span><span data-contrast=\"auto\">all connections in the pool are active and a new one needs to be created.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><i><span data-contrast=\"auto\">maxLifetime<\/span><\/i><span data-contrast=\"auto\">\u00a0controls<\/span><span data-contrast=\"auto\">\u00a0maximum lifetime of a connection\u00a0<\/span><span data-contrast=\"auto\">sitting in the pool doing nothing.\u00a0<\/span><span data-contrast=\"auto\">It is recommended to set this value<\/span><span data-contrast=\"auto\">\u00a0slightly<\/span><span data-contrast=\"auto\">\u00a0shorter than any other<\/span><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">connection\u00a0<\/span><span data-contrast=\"auto\">timeout limit<\/span><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><i><span data-contrast=\"auto\">validationTimeout<\/span><\/i><span data-contrast=\"auto\">\u00a0<\/span><span data-contrast=\"auto\">basically<\/span><span data-contrast=\"auto\">\u00a0contro<\/span><span data-contrast=\"auto\">ls how long validation test wil<\/span><span data-contrast=\"auto\">l wait before declaring a connection \u201cdead\u201d<\/span><span data-contrast=\"auto\">\u00a0and evicted from the pool<\/span><span data-contrast=\"auto\">\u00a0if backend will not respond.\u00a0<\/span><span data-contrast=\"auto\">Default is 5 sec<\/span><span data-contrast=\"auto\">\u00a0and should work well in most\u00a0<\/span><span data-contrast=\"auto\">scenarios but<\/span><span data-contrast=\"auto\">\u00a0can be decreased if you<\/span><span data-contrast=\"auto\">\u2019re looking for faster reaction times in case of transient errors.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2><span data-contrast=\"none\">Summary<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">What this article<\/span><span data-contrast=\"auto\">\u00a0and accompanied\u00a0<\/span><a href=\"https:\/\/github.com\/scoriani\/reliable-jdbc-app\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-contrast=\"none\">code sample<\/span><\/a><span data-contrast=\"auto\">\u00a0are demonstrating is that, with<\/span><span data-contrast=\"auto\">\u00a0few specific configuration options and additional code libraries<\/span><span data-contrast=\"auto\">, customers can implement Java applications for Azure SQL Database\u00a0<\/span><span data-contrast=\"auto\">that are more reliable and less impacted by transient service reconfigurations and network disconnections<\/span><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A growing number of\u00a0Azure SQL Database\u00a0customers are developing new applications in Java using a JDBC driver from Microsoft or a 3rd\u00a0party.\u00a0These drivers are\u00a0providing quite extensive support\u00a0and\u00a0covering most of database service capabilities and performance expectations but\u00a0there are a couple of areas that deserve some attention.<\/p>\n","protected":false},"author":32624,"featured_media":81,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[30,168,167],"class_list":["post-142","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sql","tag-developers","tag-jdbc","tag-reliability"],"acf":[],"blog_post_summary":"<p>A growing number of\u00a0Azure SQL Database\u00a0customers are developing new applications in Java using a JDBC driver from Microsoft or a 3rd\u00a0party.\u00a0These drivers are\u00a0providing quite extensive support\u00a0and\u00a0covering most of database service capabilities and performance expectations but\u00a0there are a couple of areas that deserve some attention.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/32624"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=142"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/142\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/81"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}