As far as I understand there are two types of DataSource
connections, javax.sql.DataSource
and javax.sql.XADataSource
, this tutorial explains that javax.sql.DataSource
give the connection the ability to be pooled and javax.sql.XADataSource
give the connection distributed transactional behavior.
I understand most XADataSource
will implement connection pooling as well as distributed transactions so I don't see the point to use a DataSource
when you could use a XADataSource
and have both.
Are there any tradeoff when choosing a XADataSource
over a DataSource
?
I understand is not mandatory for a XADataSource
to use pooled connections, is it there a way to find out if a XADataSource
uses pooled connections or only relying on the XADataSource
provider's documentation?
EDIT:
I am refering to javax.sql.DataSource
and javax.sql.XADataSource
because those are the types Tomcat 8
factory gives you:
Type should always be javax.sql.DataSource or javax.sql.XADataSource
Depending on the type a org.apache.tomcat.jdbc.pool.DataSource or a org.apache.tomcat.jdbc.pool.XADataSource will be created.
I do understand that in the end I would be using a DataSource
on my code as an API, abstracting the underlying implementation... my question is more related on the decision making process I have to go through when I am configuring Tomcat 8
(or any other server as well).
I want to have pooled connections and there are many XADataSource
implementations that will give transactional and pooled connections, so why not always use XADataSource
if I will get more? (this of course doesn't applies for a XADataSource
that doesn't implements pooled connections)
XADataSource
As explained in the second section, your code will always use the DataSource
interface (which might use a XADataSource
). If the question is when should you use a XADataSource
(eg configure it in your application server), then the answer is simple:
You use an XADataSource
if you need to have distributed transactions: that is ensure a transaction succeeds or fails across multiple resources (eg different databases).
If you don't need distributed transactions, then you can still configure an XADataSource
, but this might have some overhead in terms of memory and processing, for example extra objects (eg XAResource
) that go unused, and maybe in terms of the 'bookkeeping' done by the data source. This overhead is probably negligible though.
Some data source (eg the Tomcat pool as mentioned in your question), can either use a DataSource
or an XADataSource
as a factory to create connections (according to the JDBC spec a ConnectionPoolDataSource
should also be available as a factory, but it looks like Tomcat ignores that option). This doesn't change the way you decide what to use:
Don't need distributed transactions:
Program --uses--> Tomcat connection pool DataSource
--uses--> JDBC driver DataSource
Need distributed transactions:
Program --uses--> Tomcat connection pool DataSource
--uses--> JDBC driver XADataSource
In both cases the connection pool is provided by the Tomcat connection pool DataSource
, not by the JDBC driver (XA)DataSource
. A correct* implementation of XADataSource
will not implement connection pooling: that would be the (optional) responsibility of the DataSource
implementation that uses the XADataSource
as its factory. So that is not a reason to choose (or not choose) an XADataSource
.
Your question might stem from the confusing terminology that a XADataSource
creates XAConnection
which extends PooledConnection
. The name PooledConnection
doesn't mean it comes from a connection pool, it means that after creation these can be held in a connection pool (which would be inside the DataSource
that called XADataSource.getXAConnection
).
DataSource
and XADataSource
In JDBC the responsibility of a DataSource
is to create connections that can be used by your application. This means that it can be a very basic implementation that does nothing more than go directly to DriverManager
, but also an implementation that provides connection pooling, and support for distributed transactions.
The idea is that you can swap one implementation for the other, while your code would be untouched.
So, the code consuming connections should always use a javax.sql.DataSource
implementation. The javax.sql.XADataSource
(and javax.sql.ConnectionPoolDataSource
for that matter) are intended to be used by javax.sql.DataSource
implementations that provided advanced features like connection pooling and/or distributed transactions. They should not be used directly in your own program. As the tutorial you link says:
Similarly, when the
DataSource
implementation is implemented to work with anXADataSource
class, all of the connections it produces will automatically be connections that can be used in a distributed transaction.
In other words DataSource
is the API you use to obtain a connection, and a XADataSource
is used by a data source library that provides distributed transaction support. It obtains the XAConnection
, registers it with a distributed transaction manager, and then gives you the logical connection obtained from XAConnection.getConnection()
.
This is also a described in the JDBC 4.2 specification, section 12.1:
Distributed transactions require an infrastructure that provides these roles:
- Transaction manager — controls transaction boundaries and manages the two-phase commit protocol. This typically will be an implementation of JTA.
- JDBC drivers that implement the
XADataSource
,XAConnection
, andXAResource
interfaces. These are described in the next section.- An application-visible implementation of
DataSource
to “sit on top of” eachXADataSource
object and interact with the transaction manager. TheDataSource
implementation is typically provided by an application server.- Resource manager(s) to manage the underlying data. In the context of the JDBC API, a resource manager is a DBMS server. The term “resource manager” is borrowed from JTA to emphasize the point that distributed transactions using the JDBC API follow the architecture specified in that document.
TL;DR: You --use--> DataSource
--(potentially) uses--> XADataSource
*: Historically there has been some confusion in various JDBC implementations regarding responsibilities, and in some cases connection pools have implemented all three interfaces at the same time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With