KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfox > jdbc > xa > TxDataSource


1 /* JFox, the OpenSource J2EE Application Server
2  *
3  * Distributable under GNU LGPL license by gun.org
4  * more details please visit http://www.huihoo.org/jfox
5  */

6
7 package org.jfox.jdbc.xa;
8
9 import java.io.PrintWriter JavaDoc;
10 import java.sql.Connection JavaDoc;
11 import java.sql.SQLException JavaDoc;
12 import javax.naming.NamingException JavaDoc;
13 import javax.naming.Reference JavaDoc;
14 import javax.naming.Referenceable JavaDoc;
15 import javax.naming.StringRefAddr JavaDoc;
16 import javax.sql.DataSource JavaDoc;
17 import javax.sql.XAConnection JavaDoc;
18 import javax.sql.XADataSource JavaDoc;
19 import javax.transaction.Status JavaDoc;
20 import javax.transaction.SystemException JavaDoc;
21 import javax.transaction.Transaction JavaDoc;
22 import javax.transaction.TransactionManager JavaDoc;
23
24 import org.jfox.ioc.common.AbstractService;
25 import org.jfox.ioc.ext.ActiveComponent;
26 import org.jfox.jndi.InitialContextHelper;
27 import org.jfox.tm.TxManager;
28
29 /**
30  * 支持事务的 DataSource,在每次 getConnection 的时候,会 enlistResource
31  * work like all XADataSource's front
32  *
33  * @author <a HREF="mailto:young_yy@hotmail.com">Young Yang</a>
34  */

35
36 public class TxDataSource extends AbstractService
37                             implements DataSource JavaDoc,
38                             XADataSource JavaDoc,
39                             Referenceable JavaDoc,
40                                        ActiveComponent {
41     // 注册到 XADataSourceManager 中的名字
42
private String JavaDoc dsName = null;
43     private String JavaDoc dbUrl = null;
44     private String JavaDoc user = null;
45     private String JavaDoc password = null;
46     private int initNum = 2;
47     private int maxRest = 10;
48     private long timeout = 10 * 60 * 1000; // 10m
49
private int transactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
50
51     // 缓存 XAConnection
52
private XAConnectionPool pool = null;
53     private static TransactionManager JavaDoc tm = null;
54
55     /**
56      * 生成 XAConnectionPool, used by XADataSourceManager
57      * url: jdbc:protocol:subprotocol://serverName:portNumber;databaseName=db;user=x;password=y
58      */

59     public TxDataSource(String JavaDoc dsName, String JavaDoc dbUrl, String JavaDoc user, String JavaDoc password) {
60         this.dsName = dsName;
61         this.dbUrl = dbUrl;
62         this.user = user;
63         this.password = password;
64     }
65
66     /**
67      * 生成一个 TxDataSource,并不注册到 XADataSourceManager 中
68      */

69     TxDataSource(String JavaDoc dbUrl, String JavaDoc user, String JavaDoc password) {
70         this.dbUrl = dbUrl;
71         this.user = user;
72         this.password = password;
73     }
74
75     public int getLoginTimeout() throws SQLException JavaDoc {
76         return ((XAConnectionFactory) pool.getObjectFactory()).getLoginTimeout();
77     }
78
79     public void setLoginTimeout(int seconds) throws SQLException JavaDoc {
80         ((XAConnectionFactory) pool.getObjectFactory()).setLoginTimeout(seconds);
81     }
82
83     public PrintWriter JavaDoc getLogWriter() throws SQLException JavaDoc {
84         return ((XAConnectionFactory) pool.getObjectFactory()).getLogWriter();
85     }
86
87     public void setLogWriter(PrintWriter JavaDoc out) throws SQLException JavaDoc {
88         ((XAConnectionFactory) pool.getObjectFactory()).setLogWriter(out);
89     }
90
91     public Connection JavaDoc getConnection() throws SQLException JavaDoc {
92         return getConnection(user, password);
93     }
94
95     public Connection JavaDoc getConnection(String JavaDoc username, String JavaDoc password) throws SQLException JavaDoc {
96         return getXAConnection(username, password).getConnection();
97     }
98
99     public XAConnection JavaDoc getXAConnection() throws SQLException JavaDoc {
100         return getXAConnection(user, password);
101     }
102
103     public XAConnection JavaDoc getXAConnection(String JavaDoc user, String JavaDoc password) throws SQLException JavaDoc {
104         if(pool == null) throw new SQLException JavaDoc("please run init() to build connection pool first.");
105
106         //如果当前事务已经关联有 XAConnection,则直接返回
107
//一个事务可能关联了几个 Connection
108
int txStatus = Status.STATUS_NO_TRANSACTION;
109         Transaction JavaDoc tran = null;
110         try {
111             txStatus = tm.getStatus();
112             // 必须在事务环境中
113
if(txStatus == Status.STATUS_NO_TRANSACTION) {
114                 throw new SQLException JavaDoc("can not getXAConnection while current thread is not in Transaction context!");
115             }
116             tran = tm.getTransaction();
117             if(XAConnectionManager.isAssociated(tran, dbUrl, user, password)) {
118                 return XAConnectionManager.getXAConnection(tran, dbUrl, user, password);
119             }
120         }
121         catch(SystemException JavaDoc e) {
122             logger.error("getXAConnection associate current transaction error", e);
123         }
124
125         XAConnection JavaDoc xaconn = null;
126         try {
127             // 使用特别的 user 和 password,不会缓存
128
if(!user.equals(this.user) || !password.equals(this.password)) {
129                 xaconn = (XAConnection JavaDoc) pool.retrieveObject(user, password);
130             }
131             else {
132                 xaconn = (PoolableXAConnection) pool.retrieveObject();
133             }
134         }
135         catch(Exception JavaDoc e) {
136             logger.warn("retrieve object exception ", e);
137             if(e instanceof SQLException JavaDoc) {
138                 throw (SQLException JavaDoc) e;
139             }
140             else {
141                 throw new SQLException JavaDoc(e.getMessage());
142             }
143         }
144         return xaconn;
145     }
146
147     public Reference JavaDoc getReference() throws NamingException JavaDoc {
148         Reference JavaDoc ref = new Reference JavaDoc(getClass().getName(), XADataSourceObjectFactory.class.getName(), null);
149         ref.add(new StringRefAddr JavaDoc("user", getUser()));
150         ref.add(new StringRefAddr JavaDoc("password", getPassword()));
151         ref.add(new StringRefAddr JavaDoc("dbURL", getDbUrl()));
152         // dsName 存到 XADataSourceManager 中的名字
153
ref.add(new StringRefAddr JavaDoc("dsName", getDsName()));
154         return ref;
155     }
156
157     public String JavaDoc getDsName() {
158         return dsName;
159     }
160
161     public String JavaDoc getDbUrl() {
162         return dbUrl;
163     }
164
165     public String JavaDoc getUser() {
166         return user;
167     }
168
169     public String JavaDoc getPassword() {
170         return password;
171     }
172
173     public void setTimeout(long timeout) {
174         this.timeout = timeout;
175     }
176
177     public long getTimeout() {
178         return timeout;
179     }
180
181     public int getMaxRest() {
182         return maxRest;
183     }
184
185     public int getInitNum() {
186         return initNum;
187     }
188
189     public void setInitNum(int initNum) {
190         this.initNum = initNum;
191     }
192
193     public void setMaxRest(int maxRest) {
194         this.maxRest = maxRest;
195     }
196
197     public void setTransactionIsolation(int level) {
198         transactionIsolation = level;
199     }
200
201     public int getTransactionIsolation() {
202         return transactionIsolation;
203     }
204
205     static TransactionManager JavaDoc getTransactionManager() {
206         return tm;
207     }
208
209     protected void doInit() throws Exception JavaDoc {
210         if(tm == null) {
211             try {
212                 tm = TxManager.getInstance();
213             }
214             catch(Exception JavaDoc e) {
215                 throw new RuntimeException JavaDoc(e);
216             }
217         }
218         XAConnectionFactory xaConnFactory = new XAConnectionFactory(dbUrl, user, password);
219         xaConnFactory.setTransactionIsolation(transactionIsolation);
220         pool = new XAConnectionPool(xaConnFactory, initNum, maxRest, timeout);
221         pool.init();
222     }
223
224     protected void doDestroy() throws Exception JavaDoc {
225         pool.destroy();
226         pool = null;
227         XADataSourceManager.unregisterDataSource(dsName);
228     }
229     
230     protected void doStart() throws Exception JavaDoc {
231         InitialContextHelper.getInitialContext().rebind(getDsName(), this);
232     }
233
234     protected void doStop() throws Exception JavaDoc {
235         InitialContextHelper.getInitialContext().unbind(getDsName());
236     }
237
238     public void run() {
239     }
240
241     public static void main(String JavaDoc[] args) {
242
243     }
244 }
245
Popular Tags