Class DataSource
A pool of connections to ONE database, whichever engine that database is.
DbPool pools SQLite and only SQLite -- it opens connections from a
file path, so there is nowhere to put a host, a user or a password. That left
the server engines with the advice to share a single Database and
accept that every handler queues behind whichever exchange is on the socket,
because a Database over PostgreSQL or MySQL owns one wire connection and
synchronizes every operation on it.
Queueing is the right default for a server whose database is a local file. It is the wrong one for a server whose database is a machine across a network that is perfectly happy to run eight statements at once: there the single connection is not a safety property, it is the bottleneck. This is the same pool for all three, so which engine is behind it stops being a question the application's structure has to answer.
DataSource db = DataSource.open("postgres://user:pw@db.internal/app");
List rows = db.query("SELECT id, title FROM notes WHERE author = ?",
new Object[] {author});
The convenience methods above borrow a connection, run one statement and
release it, which is what a handler wants: it is the borrow held ACROSS
unrelated work that empties a pool. inTransaction(DataSource.Work) is the form for
several statements that have to be one, and it holds exactly one connection
for exactly the body.
Connections are opened lazily except the first, which is opened by
open(String) so that a wrong URL, an unreachable host or a refused password
fails at start-up rather than on the first request that needed the database.
An in-memory SQLite database is pooled at size one, and a configuration asking for more is REFUSED rather than quietly reduced. Each connection to ":memory:" gets its OWN private database, so a pool of them hands successive requests different empty databases -- the one case where a bigger pool is not slower but wrong, and a setting worth reporting rather than ignoring.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceA unit of work run against one borrowed connection. -
Method Summary
Modifier and TypeMethodDescriptionborrow()Takes a connection, blocking until one is free.voidclose()Closes every connection.dialect()How this pool's engine spells things.intOne statement on a borrowed connection.static DataSourcefromConfig(Config config) The pool aConfigdescribes, which is the one a server normally wants: the URL comes from the deployment rather than from the source.intHow many are open and free right now.intHow many connections this pool may hold.intHow many are open right now, borrowed or idle.longOne INSERT on a borrowed connection, answering the key the database generated.inTransaction(DataSource.Work body) One transaction on one borrowed connection.static DataSourceA pool of one around a connection somebody else opened, for code that has aDatabasealready and wants the pooled API around it.static DataSourceA pool of the default size for whatever engineurlnames.static DataSourceA pool ofsizeconnections; 0 takes the default for the engine.static DataSourceThe general form.One query on a borrowed connection.One query that returns at most one row, on a borrowed connection.voidReturns a borrowed connection to the pool.toString()Returns a string representation of the object.Borrows a connection, runs body, and returns it however body ends.
-
Method Details
-
open
A pool of the default size for whatever engineurlnames.- Throws:
IOException
-
open
A pool ofsizeconnections; 0 takes the default for the engine.- Throws:
IOException
-
open
public static DataSource open(String url, int size, int busyTimeoutMillis, long borrowTimeoutMillis) throws IOException The general form.- Parameters:
size- how many connections at most; 0 for the engine's defaultbusyTimeoutMillis- how long SQLite waits on a locked database; ignored by the server engines, which have no such settingborrowTimeoutMillis- how long a borrow waits for a free connection before failing; 0 waits forever- Throws:
IOException
-
fromConfig
The pool a
Configdescribes, which is the one a server normally wants: the URL comes from the deployment rather than from the source.With no URL configured at all this answers an in-memory SQLite database on a development profile, and refuses on any other. Defaulting silently in production is how a service comes up healthy, serves requests, writes everything into a database inside its own process and loses all of it at the next deploy.
- Throws:
IOException
-
of
A pool of one around a connection somebody else opened, for code that has a
Databasealready and wants the pooled API around it.The connection is NOT closed by
close(): it belongs to whoever opened it.- Throws:
IOException
-
borrow
Takes a connection, blocking until one is free. Release it in a finally, or prefer the methods that cannot leak one.- Throws:
IOException
-
release
Returns a borrowed connection to the pool. -
withConnection
Borrows a connection, runs body, and returns it however body ends.- Throws:
Exception
-
inTransaction
One transaction on one borrowed connection.
Everything the body does through the Database it is handed is inside that transaction. Anything it does through THIS pool is not: that borrows a second connection, which the database sees as another session entirely, and on SQLite it will simply block against the write lock the first one holds.
- Throws:
Exception
-
execute
One statement on a borrowed connection.- Throws:
IOException
-
query
One query on a borrowed connection.- Throws:
IOException
-
queryOne
One query that returns at most one row, on a borrowed connection.- Throws:
IOException
-
insert
One INSERT on a borrowed connection, answering the key the database generated.
The connection is held across the insert AND the question that reads the key back, which is what makes the answer this insert's on the engines where the key is a property of the session -- SQLite's last_insert_rowid and MySQL's LAST_INSERT_ID both answer for the connection they are asked on. A pooled insert that released between the two would read whatever the next borrower had done.
- Throws:
IOException
-
dialect
-
getMaxSize
public int getMaxSize()How many connections this pool may hold. -
getOpenCount
public int getOpenCount()How many are open right now, borrowed or idle. -
getIdleCount
public int getIdleCount()How many are open and free right now. -
close
public void close()Closes every connection. Borrowed ones are closed as they come back. -
toString
Description copied from class:ObjectReturns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + '@' + Integer.toHexString(hashCode())
-