BasicXADataSourceUsageTest for H2, HSQLDB and Derby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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