I have been searching high and low and gathered bits and pieces, apologies if this has already been answered elsewhere but I am unable to find it.
I am writing a web application in Java with Tomcat, and SQL Azure in the backend.
There are multiple servlets accessing the SQL Azure DB. I would like to use Connection Pools as managed by Tomcat 8.5
My application context.xml in META-INF is as follows:
<Context>
<Resource name="jdbc/sqlazure"
auth="Container"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
type="javax.sql.DataSource"
maxIdle="30"
username="[username]"
password="[password]"
url="jdbc:sqlserver://[database]:1433;database=BackInfo;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30"
removeAbandonedTimeout="30"
logAbandoned="true" />
</Context>
In the Java Code, I access the typical way:
InitialContext ic = new InitialContext();ds = (DataSource)ic.lookup("java:comp/env/jdbc/sqlazure");
try(Connection con = ds.getConnection())....
Everything seems to work, so let me confirm my understanding here:
I do not need to specify a separate web.xml since I'm using Tomcat 8.5. Correct ?
Azure will automatically create a pool when I connect in this manner. The number of connections in the pool etc cannot (do not need to?) be configured.
Before I realized I would have other servlets that need to access the database, I had one servlet directly creating a Datasource via SQLServerConnectionPoolDataSource and getting a connection from there. The documentation states:
SQLServerConnectionPoolDataSource is typically used in Java Application Server environments that support built-in connection pooling and require a ConnectionPoolDataSource to provide physical connections, such as Java Platform, Enterprise Edition (Java EE) application servers that provide JDBC 3.0 API spec connection pooling.
Does this mean that when I use SQLServerConnectionPoolDataSource directly to ask for a connection, it will check if Tomcat supports pooling and then is basically using JDBC mechanisms to create a pool of SQL Azure connections managed by Tomcat ?
When getting the DataSource via Tomcat JNDI lookup, using SQLServerDriver as specified in context.xml. When the web app starts up, it will check context.xml and use SQLServerDriver to connect to SQL Azure, check if pooling is supported, if yes then Tomcat is using the driver to automatically creating a connection pool DataSource that it returns ?
I also just thought of one other question. Would it make sense to have a Singleton DataSource class that returns a reference to the pooled connection DataSource, or would it be better to have each servlet lookup the datasource in its init() and store in a private variable ?
Thanks
Based on my understanding, the jdbc connection pool for SQL Server is created by Java Application, not Azure does. My suggestion is that you need to refer to the Tomcat offical documents below to understand the JNDI Resources & JDBC DataSource.
JNDI Resources: http://tomcat.apache.org/tomcat-8.5-doc/jndi-resources-howto.html
JDBC DataSource: http://tomcat.apache.org/tomcat-8.5-doc/jndi-datasource-examples-howto.html
Related
I've a Spring Boot Java application in production that uses ActiveJDBC to access a MariaDB database.
If at launch the application boots before the db server, of if the db server crashes and restarts, the apps doesn't re-estabilish the connection with the db.
ActiveJDBC is on version 1.4.13 and if possible I'd prefer not upgrading it, to avoid possible breakages. The db parameters are configured using the database.properties file and typically the usage pattern is:
try {
Base.open();
...
} finally {
Base.close();
}
Is there a way to circumvent this problem, without monitoring and relaunching the application? Maybe using connection pools? If this is the case, are there any docs or examples?
If you are using a direct JDBC connection in your database.properties file, a new connection will be open every time you execute Base.open(). This means that any old connection that is broken is not relevant anymore. If you use a JDNI pool such as:
production.jndi=java:comp/env/jdbc/acme
then you want to configure your containers' pool to ensure that every connection served from the pool is valid just before the pool serves the connection to your app. It is up to the implementation and documentation of your container/pool how to do that.
In any case, I do not think you are going to have issues.
I am currently trying to implement a simple servlet that has to communicate with our database.
I have no real prior experience with databases, so I was wondering how I should I go about this? I have downloaded the mysql-connector-java-5.1.40 from dev.mysql.
Going over some of the directions on the web for setting up the connection, it seems to only be for local mysql, but what of remote? The remote's user and pass is demo/demo; of course I would also need to log into the the remote server with my credentials. How do I go about connecting to this remote db?
Edit: So I believe I successfully connected to the DB, at least I can see it in my eclipse under data sources and the tables are present (company and stock_prices), however my eclipse still says I have an unsuitable driver even though I do have one associated with it.
The proper way of consuming a database resources in a web container (or in an application server) is through the javax.sql.DataSource abstraction. So you should configure a data source in your container. For tomcat it's as simple as creating a file named context.xml in your war's META-INF folder with the following content (replace address and credentials with your own):
<Context>
<Resource name="jdbc/[YourDatabaseName]"
auth="Container"
type="javax.sql.DataSource"
username="[DatabaseUsername]"
password="[DatabasePassword]"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql:/[yourserver]:3306/[your-db]"
maxActive="20"
maxIdle="20"/>
</Context>
Then when you want to perform a DB operation:
you either look up the data source:
DataSource ds =(DataSource) new InitialContext().lookup("java:comp/env/jdbc[YourDatabaseName]");
or simply use dependency injection for managed components like servlets:
#Resource(name="jdbc/YourDataSource")
Datasource ds;
The you just get a connection from the datasource in order to execute statements to the database.
The DB driver can be put in one of two places:
the war's lib folder
tomcat's lib folder
It's recommended to put it in tomcat's lib, because drivers are singletons and if you have several apps with different versions of the driver in the same container bad things will happen.
How do I go about connecting to this remote db?
Connecting to a remote DB is the same as connecting to alocal DB. Just pass the correct DB address in the connection string.
I am executing SQLs via following code statement.
Application server is weblogic 12c
and Spring 3.1.1 API is used.
getJdbcTemplate().execute()...
I am wondering if getJdbcTemplate() returns DB connection itself or a reference to connection pool hosted at weblogic.
And if connection is closed after sql is executed?
If you define the datasource on Weblogic level and you reference that via a JNDI lookup in your spring configuration ==> will return a connection from the pool it was configured on Weblogic.
However with Spring you can configure your own pool without using Weblogic's one.
So depends on how you use it.
Cheers.
I have a Web application running on Oracle Weblogic Server 11g.
It uses a datasource defined in the application server to connect to the Oracle Database (11g too), its class is
oracle.jdbc.xa.client.OracleXADataSource
If for some reason the database becomes not present and then comes
backs, the application is running ok (it gets exceptions while trying
to access the db but this is fine and then can again get some new
connections when the db comes back)
However, if the database is down during weblogic server startup,
the datasource is not deployed on the server and the application
throws an exception because it has not any datasource available, the
deployment is marked as failed and of course nothing does repair this
automatically.
Is there a way to make the datasource be deployed even if the database is not present during server startup ? (such that the application becomes usable when the database is back)
Why do you want to deploy an application without a valid datasource?
You could possibly fake the datasource (create a dummy datasource with the same JNDI name) and assuming that the application does not validate datasource schema at startup you will get a semi-functional running application (which will fail with the first DB interaction).
When the real datasource is up and running you won't be able to switch to it. You will still have to restart the application server.
Update:
According to the J2EE spec (1.5 version) resources are binded during the deployment process. I believe that it is possible to implement a custom Factory that will return dummy / active datasource. Does it worth the effort to implement? ;)
EE.5.6.2 Deployer’s Responsibilities
Bind the resource manager connection factory reference to a resource manager connection factory that exists in the operational environment. The Deployer may use, for example, the JNDI LinkRef mechanism to create a symbolic link to the actual JNDI name of the resource manager connection factory. The re- source manager connection factory type must be compatible with the type de- clared in the res-type element.
The option you are looking for is "Connection Creation Retries", check this link
"If set and if the database is unavailable when the data source is created, WebLogic Server attempts to create connections in the pool again after the number of seconds you specify, and will continue to attempt to create the connections until it succeeds. This option applies to connections created when the data source is created at server startup ..."
set "Initial Capacity" http://docs.oracle.com/cd/E14571_01/web.1111/e13814/jdbc_tuning.htm#i1028616 to 0: weblogic on startup will not attempt to create any connection, and will not fail if the DB is not available.
I am about to make a connection to my database and I am using EJB and JPA. I have recently started doing these technologies so I have some problems understand it all at this point:)
I know that the persistence.xml is needed in order to use JPA. It is the file where I configure how to connect to the database, that I know. However it seems like there are multiple ways of doing it.
What would be the difference (or when should I even use the one alternative over the other?) of defining properties such as username, database, password etc. in the persistence.xml file and in Glassfish? Advantages/disadvantages if any.
Underneath on the image I posted I have JDBC Resources and JDBC Connection Pools. I am a litte confused about the terminology of the two. Why don't we add properties such as username, database, password and so on in the JDBC Resources? Could someone explain the difference between them and what they mean?
JDBC Resources
A JDBC resource (data source) provides applications with a means of
connecting to a database. Typically, the administrator creates a JDBC
resource for each database accessed by the applications deployed in a
domain. (However, more than one JDBC resource can be created for a
database.)
http://download.oracle.com/docs/cd/E19316-01/820-4335/ablih/index.html
I think it strange that we add such properties on the pool but not in the resource, but I probably misunderstand the concepts.
In the "JDBC connection pools" you can create container managed JDBC data sources (with connection pooling capabilities). The data source needs to know about at least the JDBC driver, the JDBC URL, username and password.
In the "JDBC resources" you can bind those container managed JDBC data sources to one or more JNDI names so that they are by JNDI available to the deployed web application.
In the persistence.xml you can specify whether to use a local data source or to use a container managed data source. If you want to use a container managed data source, then you should specify its JNDI name. Using a container managed data source has the advantage that you can share a single data source among multiple web applications. In case of JPA, it has also the advantage that you can make use of JTA (container managed transactions) so that you don't need to call transaction.begin(), commit(), rollback() etc in every method.