DB2 StatementPool configuration issue - java

I'm trying to activate the statementPool with the db2 jdbc driver, and i m having trouble doing so.
I've tried different techniques mentionned here : http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=%2Fcom.ibm.db2z10.doc.java%2Fsrc%2Ftpc%2Fimjcc_c0052041.htm
Here is the java code :
csUrl += ":maxStatements=1000;";
System.err.println("Connecting to csUrl : " + csUrl);
DB2ConnectionPoolDataSource ds = new DB2ConnectionPoolDataSource();
//DB2SimpleDataSource ds = new DB2SimpleDataSource();
//ds = new DB2ConnectionPoolDataSource();
ds.setServerName("edited");
ds.setPortNumber(edited);
ds.setDatabaseName("edited");
ds.setCurrentSchema("edited");
ds.setMaxStatements(1000);
ds.setDriverType(4);
Connection connection = ds.getPooledConnection(csUser, csPassword).getConnection();
//Connection connection = ds.getConnection(csUser, csPassword);
//Connection connection = DriverManager.getConnection(csUrl);
//Connection connection = m_driver.connect(csUrl, propertiesUserPassword);
boolean pooling = connection.getMetaData().supportsStatementPooling();
if (pooling) {
System.err.println(">>> Pooling is ON!");
} else {
System.err.println(">>> Pooling is OFF! <<<");
}
All techniques fail according to : connection.getMetaData().supportsStatementPooling() and statementPooling is always deactivated.
I'm running DB2 Express /Linux :
Database server = DB2/LINUXX8664 10.1.2
with the matching jdbc driver.
Same code with a different db2 backend (db2 10 zOs) gives the same result, so i guess it s not an Express issue.
Client code is running on windows.
We have a in-house statement cache, but i wanted to play around with DB2's especially since it can apparently share the pool in between logical connections provided thru a PooledDataSource
Thanks :)

Related

MysqlConnectionPoolDataSource - Can not insert to mysql db using jdbc?

I have to use a custom jdbc connection pooling library to connect to mysql db.
The problem is my that inserts are not persisted in db... To narrow down the issue, I extracted the portion of the library code inserting into db and have some strange findings:
MysqlConnectionPoolDataSource ds1 = new MysqlConnectionPoolDataSource();
ds1.setUser("usr");
ds1.setPassword("pwd");
ds1.setServerName("server");
ds1.setPort(port);
ds1.setDatabaseName("dbname");
ds1.setUseSSL(false);
ds1.setAllowPublicKeyRetrieval(true);
Connection conn = ds1.getPooledConnection("usr", "pwd").getConnection();
logger.info("connection " + conn.toString());
PreparedStatement ps = null;
ResultSet rs = null;
try {
String query = "INSERT INTO ...";
ps = conn.prepareStatement(query);
int timeout = 10;
ps.setQueryTimeout(timeout);
logger.info("timeout: " + timeout);
logger.info("Starting query execution for query: " + query);
long qeStart = System.currentTimeMillis();
ps.setString(1, "...");
ps.executeUpdate();
long qeEnd = System.currentTimeMillis();
logger.info("Query execution completed in " + (qeEnd - qeStart) + "msec.");
} catch (Exception e) {
logger.error("ERROR OCCURED", e);
System.err.println("ERROR OCCURED");
e.printStackTrace();
} finally {
closeResultSet(rs);
closeStatement(ps);
closeConnection(conn);
}
The above code does NOT work when I connect to a remote mysql db with version: 8.0.11-commercial . By not working I mean there is no error, the insert is simply lost...
When I execute the same code against my local mysql db with version : 8.0.11 hosted on windows machine, it is working...
If I change connection getting code from
Connection conn = ds1.getPooledConnection("usr", "pwd").getConnection();
to:
Connection conn = ds1.getConnection();
it also starts to work against remote mysql db with version: 8.0.11-commercial...
The autocommit mode of the underlying connection is already true...
I tried to implement a custom log4j logger with the hope of seeing some trace but that did not help either:
ds1.setLogger("com.ibtech.mysqlproblem.Log4jLogger");
My custom connection pooling library uses pooled connection so I need to get the above code working. In the client I am using mysql-connector-java-8.0.11.jar.
Any help is greatly appreciated...
It seems totally unrelated but setting paranoid property to true seemed to solve my problem...
----------------Edit : Root cause understood---------------------------------------
Problem occurs when global autocommit value is 0 in the server. Issuing change user command, clears session data and autocommit setting is lost.
A workaround solution is to set autocommit flag once again once the connection is acquired...
Thanks to Filipe for analyzing the problem..
https://forums.mysql.com/read.php?39,666702,666986#msg-666986
----------------Edit : Bug created--------------------------------------
It turned out that it is a bug in the JDBC driver. A bug has been filed...
https://bugs.mysql.com/bug.php?id=91351

No suitable driver found for jdbc:sqlserver:

I know this has been asked a hundred times and I think I have read all the posts and tried every variation of the solutions. I'm using NetBeans and new to it. I'm sure I'm just missing some small step because it seems like its just not seeing the driver that I added to the library. This is the first time I have tried to connect to a database so please be gentle.
try
{
String host = "jdbc:sqlserver://Server:1433;Database";
String uName = "User";
String uPass = "Password";
Connection con = DriverManager.getConnection(host,uName,uPass);
System.out.println("Your are connected to SQLServer 2014");
}
catch (SQLException err)
{
System.out.println(err.getMessage());
}
You forgot to register the jdbc driver class.
Call
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
before calling Connection con = DriverManager.getConnection(host,uName,uPass);.
It will resolve the issue.
UPDATE
In documentation for new jdbc drivers it is declared that this step is not necessary. But in practical work, I have found that this step is required even for new drivers, otherwise you will get "No suitable driver found" error. This error occurs sometimes, for example it does not occur when you are making and running a console jar-application, but occurs when you have created and deployed a web-application.
So, I advise to register the jdbc driver class before getting the database connection via DriverManager.getConnection() call.

Java MySql Connection Through DSN

I am trying to connect to one of my MySql Databases through a System DSN I set up. The DSN is set up correctly with my SSL certs, username, password, port, and the databases populate the DSN database drop down and the "Test" connection passes. I can't seem to get a connection in Java. I have spent 2 days looking through some examples on Stack but they all refer to an Access database and using JDBC-ODBC bridge which is no longer available in Java 8. I tried using UCanAccess with Jackcess but I have gotten no where. The code below is what I have been tinkering with the last few hours. I normally connect to MySql databases with PHP and receive result in JSON or directly with JDBC driver but for this project neither are really an option. Any ideas. I appreciate the help.
//String username = "<username>";
//String password = "<password>";
//String database = "<database_name>";
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
//Connect to cllients MySql Database
Connection conn = DriverManager.getConnection("jdbc:ucanaccess:" + database);
//Call VerifyLabel(<MAC>,<MODEL>); Call provided client
CallableStatement cStmt = conn.prepareCall("{CALL verify(?, ?)}");
//MAC
cStmt.setString(1, "mac address");
//model
cStmt.setString(2, "model");
cStmt.execute();
//Getting results from "Status" column
ResultSet rs1 = cStmt.getResultSet();
//Iterate results and print.
while (rs1.next()) {
System.out.println(rs1.getString("Status"));
}
//Close connection conn
rs1.close();
} catch (SQLException ex) {
Logger.getLogger(CambiumStoredTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(CambiumStoredTest.class.getName()).log(Level.SEVERE, null, ex);
}
Using MySql Driver:
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:"+ database);
also tried:
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/"+ database);
Error for MySql Driver:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
1) DSN is most commonly assocatiated with ODBC (and often with MS-Access). Hence all the links. ODBC is NOT required for a DSN.
2) Do NOT use Ucanaccess. Use J/Connector for mySQL.
3) Make sure you can communicate with mySQL from the command line. Then focus on getting a small "hello world" JDBC app to connect. Your second and third examples look OK. Be sure to check the mySQL logs for any warnings/errors.
Well, after an entire day of trying to get this to work and sleeping on it for a couple hours I finally got it to work. UCanAccess and mysql-connector did not work. The easiest thing since no other method of connecting to this clients database was acceptable was to push this application in Java 7 rather than 8. This allowed me to Coo=nnect to my DSN with no problems. I understand that this method is not the best solution but it is what is working flawlessly and efficiently. Also, instead of using some rigged up 3rd party libs and jars, I am able to use Connector/J. Thanks everyone for trying to help me. Just incase anyone else runs into this issue, this is how I made it work.
Develope app in Java 7 - not 8.
Set Up System DSN
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//You do not need to provide username or password if it is setup in DSN
Connection conn = DriverManager.getConnection("jdbc:odbc:"+ database);

JDBC connection pool to multiple MySQL databases on the same server (with the same user and password)

I have multiple websites (about 200) that are hosted by the same Java web app. Each site has its own MySQL database. The databases are all on the same MySQL server and are all accessed with the same user name and password.
I'm currently running out of database connections because of the way that I have implemented pooling. I'm using a C3P0 ComboPooledDataSource for each site's database. This creates hundreds of connections to the database server, and the database server just can't seem to handle it.
Is there a pooling mechanism that creates a pool of database connections that can be used for all the databases hosted on a single database server?
I found out that I can create a ComboPooledDataSource for the first database. Then when I get a connection from the database pool, I can call setCatalog(name) on the connection to use any other database on the same server using C3P0 data pooling.
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/site_a");
cpds.setUser(user);
cpds.setPassword(pass);
....
Connection conn = getPool().getConnection();
conn.setCatalog("site_b");
...
Edit: Since writing this post I switched to Proxool. The same technique of setCatalog works for it, but the syntax for creating a connection is different:
try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Properties info = new Properties();
info.setProperty("proxool.maximum-connection-count", "20");
info.setProperty("proxool.house-keeping-test-sql", " select CURDATE()");
info.setProperty("user", user);
info.setProperty("password", pass);
info.setProperty("proxool.alias", "mypoolname");
info.setProperty("proxool.url", "jdbc:mysql://localhost:3306/site_a");
info.setProperty("proxool.driver", "com.mysql.jdbc.Driver");
String url = "proxool.mypoolname";
ProxoolDatabasePool pool = new ProxoolDatabasePool(url, info);
....
Connection conn = pool.getConnection();
conn.setCatalog("site_b");
...

How do you configure a DataSource in Java to connect to MS SQL Server?

I'm trying to follow Java's JDBC tutorials to write a Java program that can connect to SQL Server 2008. I'm getting lost at the point of making a connection.
The following snippet is from the tutorial:
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:comp/env/jdbc/myDB");
Connection con = ds.getConnection();
DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource()
ds.setPort(1527);
ds.setHost("localhost");
ds.setUser("APP")
ds.setPassword("APP");
Connection con = ds.getConnection();
There's no explanation of what comp/env/jdbc/myDB should point to, and I don't know how I should choose a port. Also, the object ds seems to be defined twice.
I'm using the JSQLDataSource driver, for the record. Can anyone point me in the right direction here?
http://java.sun.com/docs/books/tutorial/jdbc/basics/connecting.html
I'm not sure anyone above has really answered the question.
I found this microsoft sample useful.
The key information in there is really that the class you need is SQLServerDataSource
that is basically a configuration object - you use it something like this:
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setUser("aUser");
dataSource.setPassword("password");
dataSource.setServerName("hostname");
dataSource.setDatabaseName("db");
You would then call
dataSource.getConnection();
to get a connection object which is basically the thing you use to talk to the database.
Use
connection.prepareStatement("some sql with ? substitutions");
to make something for firing off sql and:
connection.prepareCall
for calling stored procedures.
Start with the JDBC tutorial or the Microsoft docs.
and this:
String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
Class.forName(driver);
String url = "jdbc:microsoft:sqlserver://host:1433/database";
Connection conn = DriverManager.getConnection(url, "username", "password");
Fill in your values for host, database, username, and password. The default port for SQL server is 1433.
UPDATE: Good point below. JDBC drivers can be had from both Microsoft and jTDS. I prefer the latter.
JNDI lookups have to do with Java EE app servers that support connection pooling. You can ask the app server to create a pool of connections, which can be an expensive thing to do, and loan them out to clients like library books as needed.
If you aren't using a Java EE app server or connection pooling, you have to create the connection on your own. That's where manual processes and DriverManager come in.
EXPLANATION: As for why the Sun tutorial shows DataSource twice, I'd say it's a case of poor editing. If you look above the code sample it says you can get a DataSource "by lookup or manually". The code snippet below shows both together, when it should be one or the other.
You know it's an inadvertent error because there's no way the code as written could compile. You have "ds" declared twice.
So it should read "...lookup", followed by its code snippet, and then "...manually", followed by its code snippet.
I like the jTDS driver for connecting to SQL Server. A URL will look like this:
jdbc:jtds:sqlserver://localhost/Finance;instance=sqlexpress
Check this for jTDS Url Info.
This also has some interesting information to help troubleshoot jtds to sql express sorts of problems.
DataSource ds = new SimpleDriverDataSource(new com.mysql.jdbc.Driver(),
"jdbc:mysql://database:1433;databaseName=name", "username", "password");
JdbcTemplate jdbc = new JdbcTemplate(ds);
This question has already been answered long time ago. The question was asked about JNDI lookup. With lookup you have to see the application server log to see what the connection is bound to. For example in Jboss startup, I can see:
[ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=myDB' to JNDI name 'java:myDB'
Using that name=myDB you lookup
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:myDB");
Notice how the server log and the code both point to the JNDI name java:myDB.

Categories

Resources