提交 8a3424e2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Issue 321: the database does not expect XA rollback without XA prepare (an…

Issue 321: the database does not expect XA rollback without XA prepare (an exception was unnecessarily written into the .trace.db file).
上级 70862ee8
...@@ -45,6 +45,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -45,6 +45,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
private volatile Connection handleConn; private volatile Connection handleConn;
private ArrayList<ConnectionEventListener> listeners = New.arrayList(); private ArrayList<ConnectionEventListener> listeners = New.arrayList();
private Xid currentTransaction; private Xid currentTransaction;
private boolean prepared;
static { static {
org.h2.Driver.load(); org.h2.Driver.load();
...@@ -200,6 +201,9 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -200,6 +201,9 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
rs.close(); rs.close();
Xid[] result = new Xid[list.size()]; Xid[] result = new Xid[list.size()];
list.toArray(result); list.toArray(result);
if (list.size() > 0) {
prepared = true;
}
return result; return result;
} catch (SQLException e) { } catch (SQLException e) {
XAException xa = new XAException(XAException.XAER_RMERR); XAException xa = new XAException(XAException.XAER_RMERR);
...@@ -229,6 +233,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -229,6 +233,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
try { try {
stat = physicalConn.createStatement(); stat = physicalConn.createStatement();
stat.execute("PREPARE COMMIT " + JdbcXid.toString(xid)); stat.execute("PREPARE COMMIT " + JdbcXid.toString(xid));
prepared = true;
} catch (SQLException e) { } catch (SQLException e) {
throw convertException(e); throw convertException(e);
} finally { } finally {
...@@ -247,6 +252,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -247,6 +252,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("forget("+JdbcXid.toString(xid)+");"); debugCode("forget("+JdbcXid.toString(xid)+");");
} }
prepared = false;
} }
/** /**
...@@ -262,15 +268,16 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -262,15 +268,16 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
try { try {
physicalConn.rollback(); physicalConn.rollback();
physicalConn.setAutoCommit(true); physicalConn.setAutoCommit(true);
if (prepared) {
Statement stat = null; Statement stat = null;
try { try {
stat = physicalConn.createStatement(); stat = physicalConn.createStatement();
stat.execute("ROLLBACK TRANSACTION " + JdbcXid.toString(xid)); stat.execute("ROLLBACK TRANSACTION " + JdbcXid.toString(xid));
} catch (SQLException e) {
// ignore (not a two phase commit)
} finally { } finally {
JdbcUtils.closeSilently(stat); JdbcUtils.closeSilently(stat);
} }
prepared = false;
}
} catch (SQLException e) { } catch (SQLException e) {
throw convertException(e); throw convertException(e);
} }
...@@ -295,6 +302,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -295,6 +302,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
if (!currentTransaction.equals(xid)) { if (!currentTransaction.equals(xid)) {
throw new XAException(XAException.XAER_OUTSIDE); throw new XAException(XAException.XAER_OUTSIDE);
} }
prepared = false;
} }
/** /**
...@@ -324,6 +332,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -324,6 +332,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
throw convertException(e); throw convertException(e);
} }
currentTransaction = xid; currentTransaction = xid;
prepared = false;
} }
/** /**
...@@ -344,6 +353,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes ...@@ -344,6 +353,7 @@ public class JdbcXAConnection extends TraceObject implements XAConnection, XARes
} else { } else {
stat = physicalConn.createStatement(); stat = physicalConn.createStatement();
stat.execute("COMMIT TRANSACTION " + JdbcXid.toString(xid)); stat.execute("COMMIT TRANSACTION " + JdbcXid.toString(xid));
prepared = false;
} }
physicalConn.setAutoCommit(true); physicalConn.setAutoCommit(true);
} catch (SQLException e) { } catch (SQLException e) {
......
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
package org.h2.test.jdbcx; package org.h2.test.jdbcx;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Random;
import javax.sql.XAConnection; import javax.sql.XAConnection;
import javax.sql.XADataSource; import javax.sql.XADataSource;
import javax.transaction.xa.XAResource; import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid; import javax.transaction.xa.Xid;
import org.h2.jdbcx.JdbcDataSource; import org.h2.jdbcx.JdbcDataSource;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
...@@ -36,6 +37,7 @@ public class TestXA extends TestBase { ...@@ -36,6 +37,7 @@ public class TestXA extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testRollbackWithoutPrepare();
testXAAutoCommit(); testXAAutoCommit();
deleteDb("xa"); deleteDb("xa");
testMixedXaNormal(); testMixedXaNormal();
...@@ -48,6 +50,40 @@ public class TestXA extends TestBase { ...@@ -48,6 +50,40 @@ public class TestXA extends TestBase {
deleteDb(DB_NAME2); deleteDb(DB_NAME2);
} }
private void testRollbackWithoutPrepare() throws Exception {
Xid xid = new Xid() {
public int getFormatId() {
return 3145;
}
public byte[] getGlobalTransactionId() {
return new byte[] { 1, 2, 3, 4, 5, 6, 6, 7, 8 };
}
public byte[] getBranchQualifier() {
return new byte[] { 34, 43, 33, 3, 3, 3, 33, 33, 3 };
}
};
deleteDb("xa");
JdbcDataSource ds = new JdbcDataSource();
ds.setURL(getURL("xa", true));
Connection dm = ds.getConnection();
Statement stat = dm.createStatement();
stat.execute("CREATE TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY, VAL INT)");
stat.execute("INSERT INTO TEST(ID,VAL) VALUES (1,1)");
dm.close();
XAConnection c = ds.getXAConnection();
XAResource xa = c.getXAResource();
Connection connection = c.getConnection();
xa.start(xid, XAResource.TMJOIN);
PreparedStatement ps = connection.prepareStatement("UPDATE TEST SET VAL=? WHERE ID=?");
ps.setInt(1, new Random().nextInt());
ps.setInt(2, 1);
ps.close();
xa.rollback(xid);
connection.close();
c.close();
deleteDb("xa");
}
private void testMixedXaNormal() throws Exception { private void testMixedXaNormal() throws Exception {
JdbcDataSource ds = new JdbcDataSource(); JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:mem:test"); ds.setURL("jdbc:h2:mem:test");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论