Skip to content

Instantly share code, notes, and snippets.

@cs224
Created August 12, 2014 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cs224/e0d33aad160f889ac51a to your computer and use it in GitHub Desktop.
Save cs224/e0d33aad160f889ac51a to your computer and use it in GitHub Desktop.
BasicXADataSourceUsageTest for H2, HSQLDB and Derby
package xaresource;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.apache.derby.jdbc.EmbeddedXADataSource40;
import org.apache.derby.tools.ij;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.tools.RunScript;
import org.hsqldb.cmdline.SqlFile;
import org.hsqldb.cmdline.SqlToolError;
import org.hsqldb.jdbc.pool.JDBCXADataSource;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BasicXADataSourceUsageTest {
private static final Logger logger = LoggerFactory.getLogger(BasicXADataSourceUsageTest.class);
public XADataSource dataSource(String id) {
return hsqldbDataSource(id);
}
@Test
public void testXAResourceInteractionWithXADataSourceSimpleCommitWorkflow() throws XAException, SQLException {
String id = "myid";
XADataSource ds = dataSource(id);
PreparedStatement statement = ds.getXAConnection().getConnection().prepareStatement("INSERT INTO counter VALUES (?, ?)");
statement.setString(1, id);
statement.setLong(2, 0);
int executeUpdate = statement.executeUpdate();
if(executeUpdate == 0) {
fail("intiialization did not work.");
}
Xid xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
XAConnection connection = ds.getXAConnection();
XAResource xaresource = connection.getXAResource();
xaresource.start(xid, XAResource.TMNOFLAGS);
statement = connection.getConnection().prepareStatement("update counter set value = ? where NAME = ?");
statement.setLong(1, 5);
statement.setString(2, id);
executeUpdate = statement.executeUpdate();
if(executeUpdate == 0) {
fail("update did not work.");
}
xaresource.end(xid, XAResource.TMSUCCESS);
int ret = xaresource.prepare(xid);
if (ret == XAResource.XA_OK) {
xaresource.commit(xid, false);
} else {
fail("Expected to get a 'ret == XAResource.XA_OK'.");
}
connection.close();
connection = ds.getXAConnection();
long value = -1;
statement = connection.getConnection().prepareStatement("select value from COUNTER where NAME = ?");
statement.setString(1, id);
try(ResultSet resultSet = statement.executeQuery();) {
if (resultSet.next()) {
value = resultSet.getLong(1);
logger.debug("value: '" + value + "'");
}
}
assertThat("The value after a rollback has to be the original value!", value, is(5L));
}
@Test
public void testXAResourceInteractionWithXADataSourceSimpleRollbackWorkflow() throws XAException, SQLException {
String id = "myidR";
XADataSource ds = dataSource(id);
PreparedStatement statement = ds.getXAConnection().getConnection().prepareStatement("INSERT INTO counter VALUES (?, ?)");
statement.setString(1, id);
statement.setLong(2, 0);
int executeUpdate = statement.executeUpdate();
if(executeUpdate == 0) {
fail("intiialization did not work.");
}
Xid xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
XAConnection connection = ds.getXAConnection();
XAResource xaresource = connection.getXAResource();
xaresource.start(xid, XAResource.TMNOFLAGS);
statement = connection.getConnection().prepareStatement("update counter set value = ? where NAME = ?");
statement.setLong(1, 5);
statement.setString(2, id);
executeUpdate = statement.executeUpdate();
if(executeUpdate == 0) {
fail("update did not work.");
}
xaresource.end(xid, XAResource.TMSUCCESS);
xaresource.prepare(xid);
xaresource.rollback(xid);
connection.close();
connection = ds.getXAConnection();
long value = -1;
statement = connection.getConnection().prepareStatement("select value from COUNTER where NAME = ?");
statement.setString(1, id);
try(ResultSet resultSet = statement.executeQuery();) {
if (resultSet.next()) {
value = resultSet.getLong(1);
logger.debug("value: '" + value + "'");
}
}
assertThat("The value after a rollback has to be the original value!", value, is(0L));
}
protected XADataSource h2DataSource(String dbId) {
JdbcDataSource dataSource = new JdbcDataSource();
final String JDBC_URL_PATTERN = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;TRACE_LEVEL_FILE=4";
final String USER = "sa";
final String PASSWORD = "";
final String jdbcUrl = String.format(JDBC_URL_PATTERN, dbId);
try {
RunScript.execute(jdbcUrl, USER, PASSWORD, "src/test/sql/counter-schema-h2.sql", StandardCharsets.UTF_8, false);
} catch (SQLException e) {
throw new RuntimeException("The schema initialization of the counter did not work.", e);
}
dataSource.setURL(jdbcUrl);
dataSource.setUser(USER);
dataSource.setPassword(PASSWORD);
return dataSource;
}
// http://meri-stuff.blogspot.de/2012/01/running-jndi-and-jpa-without-j2ee.html
// http://www.jluger.de/blog/20110212_datasource_and_embedded_derby.html
protected XADataSource derbyDataSource(String dbId) {
EmbeddedXADataSource40 dataSource = new EmbeddedXADataSource40();
//final String JDBC_URL_PATTERN = "jdbc:derby:memory:%s;create=true";
final String USER = "";
final String PASSWORD = "";
//final String jdbcUrl = String.format(JDBC_URL_PATTERN, dbId);
//dataSource.setURL(jdbcUrl);
dataSource.setDatabaseName("memory:" + dbId);
dataSource.setCreateDatabase("create");
dataSource.setUser(USER);
dataSource.setPassword(PASSWORD);
try {
FileInputStream fileStream = new FileInputStream("src/test/sql/counter-schema-derby.txt");
ij.runScript(dataSource.getConnection(), fileStream, "UTF-8", System.out, "UTF-8");
} catch (Exception e) {
throw new RuntimeException("The schema initialization of the counter did not work.", e);
}
return dataSource;
}
protected XADataSource hsqldbDataSource(String dbId) {
JDBCXADataSource dataSource;
try {
dataSource = new JDBCXADataSource();
} catch (SQLException e1) {
throw new RuntimeException("The initialization of the JDBCXADataSource failed.");
}
final String JDBC_URL_PATTERN = "jdbc:hsqldb:mem:%s;DB_CLOSE_DELAY=-1";
final String USER = "sa";
final String PASSWORD = "";
final String jdbcUrl = String.format(JDBC_URL_PATTERN, dbId);
dataSource.setUrl(jdbcUrl);
dataSource.setUser(USER);
dataSource.setPassword(PASSWORD);
try {
SqlFile f = new SqlFile(new File("./src/test/sql/counter-schema-hsqldb.sql"));
f.setAutoClose(true);
f.setConnection(dataSource.getXAConnection().getConnection());
f.execute();
} catch (SQLException e) {
throw new RuntimeException("The schema initialization of the counter did not work.", e);
} catch (IOException e) {
throw new RuntimeException("The schema initialization of the counter did not work.", e);
} catch (SqlToolError e) {
throw new RuntimeException("The schema initialization of the counter did not work.", e);
}
return dataSource;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment