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
Related
How to create an application which can handle thousand of jdbc connection at runtime without implementing connection pool ? AFAIK to establish connection pool, we need username, passowrd and required dbinstance url but here all of them will be provided at runtime to connect particular database, and there would be more than 1000 user at one time to connect to set of databases.(memory intensive !)
So typically it going to be like this:
Users: User-A,User-B,User-C.....User-n
db: DB1, DB2, DB3....DBn
Can anyone please guide me how can I achieve this task ?
I only have one thing in my mind, i.e. to create single connection with each session and use it whereever required specific to that user.
I've used Apache Commons DBCP2 for connection pooling, MyBatis-Spring implementation, Spring and Vaadin for different application but not sure if anyone of them gonna help me !
Here's another approach:
Oracle supports proxy authentication. It would work something like this:
setup limited rights user for your application (say webgui)
connect to database as webgui (w connection pooling)
authenticate the real user (say JoeSmith) by simply trying to connect as him (JoeSmith/password), perhaps w a second connection
in first connection change user to JoeSmith (not sure what oracle syntax is, in postgres it's SET ROLE)
reset user at end of database session
EclipseLink has a postAcquireClientSession method, not sure about MyBatis
You might have to wipe any caching in your ORM if it uses it
Finally, I had to settle down with following approach. Though I am not sure if its a good approach.
I created a SqlSessionFactory by providing DataSource with dynamic Username, Password and Database.
public SqlSessionFactory build() throws IOException, SQLException
{
OracleDataSource dataSource = new OracleDataSource();
dataSource.setURL(this.dbUrl);
dataSource.setUser(this.dbUsername);
dataSource.setPassword(this.dbPassword);
dataSource.setDriverType(properties.getProperty("db.driver"));
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment(properties.getProperty("db.environment"), transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMappers("com.app.dao");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(configuration);
// final test connection to db
sessionFactory.openSession().getConnection();
return sessionFactory;
}
Then I am getting one SqlSession out of factory:
SqlSession session = sessionFactory.openSession();
and I am setting it across Vaadin session :(, so that it would be available throughout session. Hence I can use it whenever I need by taking it from session.
UI.getCurrent().getSession().setAttribute(SqlSession.class,session);
I am discarding it when logout:
UI.getCurrent().getSession().setAttribute(SqlSession.class, null);
I feel its dirty and may create memory issue. but didn't find any other easy solution. Please feel free to comment or answer.
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.
I'm looking for some advice on the proper way to set up mongoDB for my web application that runs with java.
From the mongoDB tutorial, i understand that I should have only one instance of the Mongo class.
The Mongo class is designed to be thread safe and shared among threads. Typically you create only 1 instance for a given DB cluster and use it across your app.
So I've got a singleton provider for this (I'm using guice for injection)
#Singleton
public class MongoProvider implements Provider<Mongo> {
private Mongo mongo;
public Mongo get() {
if (mongo == null)
mongo = new Mongo("localhost", 27017);
return mongo;
}
}
And whenever I have to work with mongo in my webapp i inject the provider and get the same instance of mongo.
public class MyService {
private Provider<Mongo> mongoProvider;
#Inject
private MyService(Provider<Mongo> mongoProvider) {
this.mongoProvider = mongoProvider;
}
public void execute() {
DB db = mongoProvider.get().getDB("mydatabase");
DBCollection coll = db.getCollection("mycollection");
// Do stuff in collection
...
}
}
What I find weird is that everytime i access my database, i get logs like this from mongo :
[initandlisten] connection accepted from 192.168.1.33:54297 #15
[initandlisten] connection accepted from 192.168.1.33:54299 #16
So far, I haven't had any problems but I'm wondering if it's good practice and if I won't run into any problems when the number of connections accepted gets too high.
Should I also have only one instance of the DB object for my entire app ?
Do I have to configure MongoDB differently to automatically close the connections after some time ? Or do I have to close connections manually ? I've read something about using the close() method on Mongo but I'm not sure when or if to call it.
Thank you for you advice.
This is good practice. Each instance of Mongo manages a connection pool, so you will see multiple connections in the mongod logs, one for each connection in the pool. The default pool size is 10, but that can be configures using the connectionsPerHost field in MongoOptions.
Mongo instances also maintain a cache of DB instances, so you don't have to worry about maintaining those as singletons yourself.
You do not have to configure Mongo to automatically close connections. You can call Mongo#close at the appropriate time to close all the sockets in the connection pool.
Founded something like this om MondoDB site:
"The Java MongoDB driver is thread safe. If you are using in a web serving environment, for example, you should create a single MongoClient instance, and you can use it in every request. The MongoClient object maintains an internal pool of connections to the database (default pool size of 10). For every request to the DB (find, insert, etc) the Java thread will obtain a connection from the pool, execute the operation, and release the connection. This means the connection (socket) used may be different each time."
And from FAQ from MongoSite which I think completely anwsers on you question.
http://docs.mongodb.org/manual/faq/developers/#why-does-mongodb-log-so-many-connection-accepted-events
How many connection will hold for a single hibernate session where there is only one DB?
there is one connection per session.
the connection is opened only if the session needs to send JDBC queries
you should avoid using the underlying connection. The connection() method has been deprecated. If you need to perform raw jdbc operations, use the doWork(..) method (if your hibernate version is the latest)
At a given time given session will only hold one connection
which you can access with the connect() method.
The connection used can be changed though using the reconnect() method.
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.