开发运行环境:WebLogic 12.1.1 开发版 + Oracle XE Database 11gR2
本文最后一次修改日期:2013-06-16
测试环境:1个WebLogic Server,两个Oracle XE数据库,其中WebLogic Server上建立了两个DataSource指向两个Oracle XE数据库。
测试代码如下:
import java.util.Hashtable;
import java.sql.Connection;
import java.sql.Statement;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
import oracle.jdbc.xa.client.OracleXADataSource;
public class UserTransactionXATest {
private static Context context = null;
public static void main(String[] args) {
UserTransactionXATest test = new UserTransactionXATest();
UserTransaction tran = null;
context = getInitialContext();
try {
tran = (UserTransaction)context.lookup("javax.transaction.UserTransaction");
tran.begin();
test.doTran1();
//int divideBy0 = 5/0;
test.doTran2();
tran.commit();
} catch (Exception e) {
e.printStackTrace();
try {
tran.rollback();
} catch (Exception ex) {
System.out.println("Rollback Exception: " + ex);
}
}
}
// public static void main(String[] args) {
// UserTransactionXATest test = new UserTransactionXATest();
// context = getInitialContext();
// try {
// test.doTran1();
// test.doTran2();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public void doTran1() throws Exception {
Connection hr1 = null;
hr1 = getConnection("jdbc/hr1DS");
//hr1 = getXAConnection("192.168.0.101");
hr1.setAutoCommit(false);
Statement stm1 = hr1.createStatement();
stm1.execute("DELETE FROM jobs WHERE job_id='CEO1'");
stm1.execute("INSERT INTO jobs VALUES('CEO1', 'CEO1', 1,2)");
stm1.close();
if (hr1 != null)
hr1.close();
}
public void doTran2() throws Exception {
Connection hr2 = null;
hr2 = getConnection("jdbc/hr2DS");
//hr2 = getXAConnection("192.168.0.103");
hr2.setAutoCommit(false);
Statement stm2 = hr2.createStatement();
stm2.execute("DELETE FROM jobs WHERE job_id='CEO2'");
stm2.execute("INSERT INTO jobs VALUES('CEO2', 'CEO2', 1,2)");
stm2.close();
if (hr2 != null)
hr2.close();
}
private static Context getInitialContext() {
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://127.0.0.1:7001");
//env.put(Context.SECURITY_PRINCIPAL, "weblogic");
//env.put(Context.SECURITY_CREDENTIALS, "welcome1");
return new InitialContext(env);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static Connection getConnection(String jndi) throws Exception {
DataSource ds = (DataSource)context.lookup(jndi);
Connection conn = ds.getConnection();
return conn;
}
public static Connection getXAConnection(String ip) throws Exception {
OracleXADataSource oxaDS = new OracleXADataSource();
oxaDS.setDatabaseName("XE");
oxaDS.setServerName(ip);
oxaDS.setPortNumber(1521);
oxaDS.setUser("hr");
oxaDS.setPassword("hr");
oxaDS.setURL("jdbc:oracle:thin:@" + ip + ":1521:XE");
return oxaDS.getXAConnection().getConnection();
}
}
(1)测试1:代码如上。
结果:不抛出异常:hr1和hr2的数据都成功正确插入各自的数据库库了。
(2)测试2: 暂停HR2 DataSource,这时会抛出异常:Caused by: java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceDisabledException: Pool HR2 JDBC Data Source is Suspended, cannot allocate resources to applications.
结果:hr1和hr2的数据都没有插入各自的数据库库了,和我们预期的一样。 因为doTran2()方法抛出异常,导致doTran1()中的事务回滚了。
这时,笔者有一个疑问,如果不使用UserTransaction会怎样呢?
(3)测试3:在测试2的基础上,注释main函数(使用了UserTransaction),打开另一个main函数(没有使用UserTransaction)。
结果:hr1和hr2的数据依然没有插入各自的数据库库了, doTran2()方法抛出异常,依然导致doTran1()中的事务回滚了。
似乎使用UserTransaction和不使用UserTransaction没有什么区别。
(4)测试4:在测试3的基础上,设置doTran1和doTran2中的setAutoCommit(true);,取代原来的设置false。
结果:hr1的数据插入数据库库了,而hr2的数据没有插入数据库。虽然doTran2()方法抛出异常,但并没有影响doTran1()中的事务。
(5)测试5:在测试4的基础上,注释main函数(没有使用UserTransaction),打开另一个main函数(使用了UserTransaction)。
结果:hr1和hr2的数据都没有插入各自的数据库库了,和我们预期的一样。
doTran2()方法抛出异常,导致doTran1()中的事务回滚了。也就是说,UserTransaction的全局事务还是起作用了。
参考文献:
1. http://www.oschina.net/question/234345_51230
没有评论:
发表评论