📄 resourceadapter.java
字号:
* extends extends* | |* |-----------------| |-----------------------|* | EmbedConnection |-- ?-->| TransactionResource |* |-----------------| |-----------------------|** * <BR><BR>* When user ask for a PooledConnection via a PooledDataSource, the following* objects exists * <BR>* |-------------------------------|* | <B>EmbeddedConnectionPoolDataSource</B> |* |-------------------------------|* | ||* | ||* extends produces* | ||* | \/* | |-----------------------| |----------------------|* | | <B>DB2jPooledConnection</B> |==>| <B>BrokeredConnection</B> |* | |-----------------------| |----------------------|* | | ^ |* | has A | has A* | | | |* |-----------------| | --------------------* | EmbeddedDataSource | |* |-----------------| |* | |* has A |* | |* V V* |------------| |----------------------| |-----------------------|* | JDBCDriver |=produces=>| EmbedConnection |==>| TransactionResource |* | LocalDriver| |----------------------| |-----------------------|* |------------| * * * * <BR><BR>* When user ask for a (normal) Connection via a DataSource, the following* objects exists. The EmbeddedDataSource is just a wrapper for the JDBCDriver.* <BR>* |-----------------|* | <B>EmbeddedDataSource</B> |* |-----------------|* |* has A* |* V* |------------| |-----------------| |-----------------------|* | JDBCDriver |==produces=>| <B>EmbedConnection</B> |- ?->| TransactionResource |* | LocalDriver| |-----------------| |-----------------------|* |------------| </PRE> <P>XADataSource inherits DataSource methods from EmbeddedDataSource. It also implements ResourceAdapter, whose main job is to keep track of run time global transactions. A global transaction table maps XIDs to XATransactionResource. XADataSource also has a XAResourceManager, which implements XAResource functionality in the Store. <P>XAConnection is the one thing that unites a global connection and the XAResource that delineates the global transaction. This is where the real XAResource functionality is implemented. All XAResource calls to the XAResource object as well as Connection call to the BrokeredConnection channels thrus the XAConnection, which makes sure only one thread can be accessing the DB2jPooledConnection at any given time. <P>XAResource and BrokeredConnection[23]0 are the two objects we give back to the TM and the user application respectively to control a distributed transaction. According to the XA spec, the app server is supposed to make sure that these objects are not used the same time by multiple threads, but we don't trust the app server. Therefore, we channel everthing back to the XAConnection. <P>The MT consideration is actually more complicated than this, because a XAResource is allowed to control any transaction, not just the one its XAConnection is current attached to. So it is not sufficient to just synchronized on XAConnection to guarentee single thread access to the underlying transaction context. To control some arbitrary global transaction, the TM can call XAResource to prepare any Xid. To do that, the XAResource pass the request to the XAConnection, the XAConnection ask the XADataSource to find the XATransactionResource, sets up the thread's context, and call ask the XATransactionResource to prepare. The XATransactionResource is synchronized to prevent some other thread from attaching, commiting, and in any way calling on the the same transaction context. If any error is thrown, it is handled with the context of the transaction being prepared. After the error is handled, the old context (the one where the XAResource is really attached to), is restored. While this monkey business is going on, the thread that holds the connection the XAConnection is supposed to be attached to is blocked out. It can resume after its XAConnection restored its context. (Here is where I am not really sure what happens since that thread obviously doesn't know about all these hanky panky caused by the thread holding the XAResource commiting, preparing and rolling back some other irrelavant transactions, so how would its context be affected in any way?). <P>DB2jPooledConnection implements PooledConnection, is hands out these connection handles which allows some app server to do connection pooling. This is a very thin layer. A connection handle implements a Connection by passing thru all calls to the underlaying connection. In this case, it passes Connection call thru the DB2jPooledConnection to the DetachableConnection underneath. <P>EmbeddedDataSource implements JNDI and is a replacement for Driver. <P>The LocalDriver can now produce a DetachableConnection as well as a EmbedConnection (which is the pre-JTA Connection that cannot detach and attach to different transactions). The way the LocalDriver knows to create a DetachableConnection versus a EmbedConnection is thru some extremely hackish URL settings. This thing is very ugly and a more elegant way can (and should) no doubt be found. <P>DetachableConnection is a connection which can detach and attach to different XATransactionResource, and can be totally unattached to any transaction. <P>XATransactionResource is a bundle of things that sets up a connection with all the stuff it needs to actually talk to the database, do error handling, etc. It is also the object that lives in the transaction table managed by the ResourceAdapter (XADataSource). A XAResource (which may or may not be attached to a transaction) can commit, prepare, or rollback any global transaction that is not attached to an XAConnection. To do that, the ResourceAdapter fishes out the XATransactionResource, set up the context, and do the commit processing/error handling on the current thread. <P>Local Connection is the same old local Connection except one difference. Pre-JTA, a localConnection uses itself (or a root Connection) as the object to synchronized upon so that multiple threads getting hold of the same Connection object cannot simultaneously issue calls to the underlying transaction or context (since those things must be single thread access). With JTA, the object of synchronization is the TransactionResource itself. This part has not been well thought through and is probably wrong. <P>TransactionResource is a base class for XATransactionResource. For a local transaction which cannot be detached from a connection, there is no need to encapsulate a bundle of things to set up a connection, so a TransactionResource (probably misnamed) has nothing and is used only for synchronization purposes. This part has not been well thought throught and is probably wrong. <P>The non-XA PooledConnection is just a thin veneer over the normal connection. I now have it over a Detachable connection just to simplify the inheritence (XAConnection need to extend PooledConnection and XAConnect needs to be detachable. However, PooledConnection itself need not be detachable). It could be changed around to have LocalDriver producing either EmbedConnection or XAConnection, and have the XAConnection implements detachable. But the current way is simpler. */public interface ResourceAdapter { /** If a run time global transaction exists, the resource adapter will find it and return a capsule of information so that a Connection can be attached to the transaction. @param xid the global transaction id @return the transaction resource if the xid correspond to a run time transaction, otherwise return null */ //XATransactionResource findTransaction(XAXactId xid); /** Start a run time global transaction. Add this to the list of transactions managed by this resource adapter. @return true if transaction can be added, otherwise false (dupid). */ //boolean addTransaction(XATransactionResource tr); /** Terminates a run time global transction. Remove this from the list of transactions managed by this resource adapter. */ //void removeTransaction(XATransactionResource tr); /** Let a xaResource get the XAResourceManager to commit or rollback an in-doubt transaction. */ XAResourceManager getXAResourceManager(); /** Get the context service factory. */ //ContextService getContextServiceFactory(); /** Is the Resource Manager active */ boolean isActive(); public Object findConnection(XAXactId xid); public boolean addConnection(XAXactId xid, Object conn); public Object removeConnection(XAXactId xid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -