I want to use pooled connections with Java (because it is costly to create one connection per thread) so I'm using the MysqlConnectionPoolDataSource() object. I'm persisting my data source across threads. So, I'm only using one datasource throughout the application like this:
startRegistry(); // creates an RMI registry for MySQL
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerName("serverIP");
dataSource.setPort(3306);
dataSource.setDatabaseName("dbname");
InitialContext context = createContext(); // Creates a context
context.rebind("MySQLDS", dataSource);
Now that I have my datasource created, I'm doing the following in each separate thread:
PooledConnection connect = dataSource.getPooledConnection();
Connection sqlConnection = connect.getConnection();
Statement state = sqlConnection.createStatement();
ResultSet result = state.executeQuery("select * from someTable");
// Continue processing results
I guess what I'm confused on is the call to dataSource.getPooledConnection();
Is this really fetching a pooled connection? And is this thread safe?
I noticed that PooledConnection has methods like notify() and wait()... meaning that I don't think it is doing what I think it is doing...
Also, when and how should I release the connection?
I'm wondering if it would be more beneficial to roll my own because then I'd be more familiar with everything, but I don't really want to reinvent the wheel in this case :).
Thanks SO
This is not the right way. The datasource needs to be managed by whatever container you're running the application in. The MysqlConnectionPoolDataSource is not a connection pool. It is just a concrete implementation of the javax.sql.DataSource interface. You normally define it in the JNDI context and obtain it from there. Also MySQL itself states it all explicitly in their documentation.
Now, how to use it depends on the purpose of the application. If it is a web application, then you need to refer the JNDI resources documentation of the servletcontainer/appserver in question. If it is for example Tomcat, then you can find it here. If you're running a client application --for which I would highly question the value of a connection pool--, then you need to look for a connection pooling framework which can make use of the MySQL-provided connection pooled datasource, such as C3P0.
The other problem with the code which you posted is that the PooledConnection#getConnection() will return the underlying connection which is thus not a pooled connection. Calling close on it won't return the connection to the pool, but just really close it. The pool has to create a new connection everytime.
Then the threadsafety story, that depends on the real connection pooling framework in question. C3P0 has proven its robustness in years, you don't worry about it as long as you write JDBC code according the standard idiom, i.e. use only the JDBC interfaces and acquire and close all resources (Connection, Statement and ResultSet) in shortest possible scope.
Related
I've read the documentation and I understand how Propagation.REQUIRES_NEW works but
Create a new transaction, and suspend the current transaction if one exists. Analogous to the EJB transaction attribute of the same name.
NOTE: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to org.springframework.transaction.jta.JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available to it (which is server-specific in standard Java EE).
See Also:
org.springframework.transaction.jta.JtaTransactionManager.setTransactionManager
I can't understand how suspension could work.
For a single level transaction I suppose that spring creates the code like this:
Connection connection = DriverManager.getConnection(...);
try {
connection.setAutoCommit(false);
PreparedStatement firstStatement = connection.prepareStatement(...);
firstStatement.executeUpdate();
PreparedStatement secondStatement = connection.prepareStatement(...);
secondStatement.executeUpdate();
connection.commit();
} catch (Exception e) {
connection.rollback();
}
Could you please provide an example for the Propagation.REQUIRES_NEW?
Is it done somehow via jdbc savepoint?
but I can't understand how suspension could work.
It mostly doesn't.
Is it done somehow via jdbc savepoint ?
JDBC doesn't support the notion of suspending transactions (it supports the notion of subtransactions, though - that's what savepoints are about. JDBC does, that is - many DB engines do not).
So how does it work?
By moving beyond the confines of JDBC. The database needs to support it, and the driver also needs to support it, outside of the JDBC API. So, via a non-JDBC-based DB interaction model, or by sending an SQL command.
For example, In WebLogic, there's the WebLogic TransactionManager. That's not open source, so I have no idea how it works, but the fact that it's a separate API (not JDBC) is rather telling.
It's also telling that the javadoc of JtaTransactionManager says that there are only 2 known implementations, and that these implementations steer quite close to the definitions in JTA.
Straight from that javadoc:
WebSphere-specific PlatformTransactionManager implementation that delegates to a UOWManager instance, obtained from WebSphere's JNDI environment.
So, JNDI then. "Voodoo skip JDBC talk directly to the database magic" indeed.
that's a question which has confuse me a lot.
for example:
when I design the Dao layer,sometimes,I must do some insert operation,and than
I should do some query such as select the data's id by auto-generate in db.
my question was that:
when I use spring to help manage datasource,
when I do more than two sql operation one by one,
how many times the java client connect to the db?? only one ? or more?
code,such as fellows:
getSimpleJdbcTemplate().update(some params...);
getSimpleJdbcTemplate().query(some params...);
It depends on your Transactional settings.
Spring-transactions in local mode, work on a thread-local connection for all the db activities within single transaction.
If you have not configured transactions, then basically each DB call will retrieve connection from datasource using Datasource.getConnection()
In terms client connecting to DB, if you are using datasource with connection pooling capability, then connections are returned from the pool.
But if datasource is not backed by pool, then it will instantiate connection to DB server on demand ( on getConnection() ) call
In order to efficiently use connection pooling via BoneCP while programming a Netty server- where is the correct place for the connection pool and where to get a new connection for that pool?
At a glance- I'm thinking that BoneCP should be some sort of global/singleton initialized just once in the main server, and then each handler (i.e. the class passed as "handler" to the pipeline) references that singleton to grab a new connection... but I don't see any examples of that on the net and, being new to Java, I'm a little concerned to jump right in with that approach. Would be great to hear an experienced voice!
Yes, a channel handler can very well use the BoneCP connection pool, but you should definitively insert an ExecutionHandler in front of the BoneCP handler. You do not want to issue blocking db calls in a netty IO worker thread.
There's also this defined in bonecp:
public ListenableFuture getAsyncConnection(){
return this.asyncExecutor.submit(new Callable<Connection>() {
public Connection call() throws Exception {
return getConnection();
}});
}
I'm using org.apache.commons.dbcp.BasicDataSource as my datasource implementation, my code geting connection and closing the connection like this:
Connection conn = dataSource.getConnection();
when I finished the connection work I will close it
conn.close();
My question is: the conn.close() is really close, so when the connection be closed like conn.close(), how is datasource doing. I heard that the datasource connection close is not really close, just is release, but I can't find the release API from datasource class. I want to know how does datasource manage the creation, close and release of database connection.
By the way a little question: how does datasource refresh the connection, I mean if the connections of the datasource haven't been used for one year, how does datasource keep the connections available?
DataSource (javax.sql.DataSource) represents an abstract concept of something you can get database connections from.
So, DataSource itself doesn't define any details of how connections are managed, and different implementations of DataSource may manage connections in different ways:
A naive implementation (such as Spring's DriverManagerDataSource) may create a new connection each time you request it, and in this case close() actually closes connections.
An implementation backed by a connection pool (such as Apache DBCP or c3p0) returns existing connections from the pool. Connection object returned by such an implementation is a proxy, and its close() method is overriden to return connection to the pool instead of closing it.
If you want to know how exactly your connection pool manages connections, check documentation of your connection pool implementation.
The close() call on a connection from a datasource doesn't necessarily close the database connection. It would merely return the connection to the pool for reuse. The way this is done is, the actual connection to the database is decorated with a PooledConnection sort of class and the close() method on this PooledConnection is overridden to just mark the connection as available.
Currently I'm using a separate DBConnectionManager class to handle my connection pooling, but I also realized that this was the wrong way to go as the servlet was not calling the same pool each time a doGet() is performed.
Can someone explain to me why the above is happening?
Is JNDI the way to go for java servlets with tomcat for proper connection pooling?
I have links to 2 articles, is this the correct way to implement connection pooling with servlets?
http://www.javaranch.com/journal/200601/JDBCConnectionPooling.html
http://onjava.com/onjava/2006/04/19/database-connection-pooling-with-tomcat.html
Is it possible to save the db manager object in the context like so:
mtdb = (MTDbManager) context.getAttribute("MTDBMANAGER");
if (mtdb == null) {
System.out
.println("MTDbManager is null, reinitialize MTDbManager");
initMTDB(config);
context.setAttribute("MTDBMANAGER", mtdb);
}
And then I call mtdb.getInstance().getConnection() and it will always reference this object.
Thanks.
Generally, the best advice is to leave the connection pooling to the application server. Just look up the data source using JNDI, and let the application server handle the rest. That makes your application portable (different application servers have different pooling mechanisms and settings) and most likely to be most efficient.
Have a look at, and use, C3P0 instead of rolling your own solution: http://sourceforge.net/projects/c3p0/