use of org.h2.mvstore.db.TransactionStore.Transaction in project h2database by h2database.
the class Server method startWebServer.
/**
* Start a web server and a browser that uses the given connection. The
* current transaction is preserved. This is specially useful to manually
* inspect the database when debugging. This method return as soon as the
* user has disconnected.
*
* @param conn the database connection (the database must be open)
* @param ignoreProperties if {@code true} properties from
* {@code .h2.server.properties} will be ignored
*/
public static void startWebServer(Connection conn, boolean ignoreProperties) throws SQLException {
WebServer webServer = new WebServer();
String[] args;
if (ignoreProperties) {
args = new String[] { "-webPort", "0", "-properties", "null" };
} else {
args = new String[] { "-webPort", "0" };
}
Server web = new Server(webServer, args);
web.start();
Server server = new Server();
server.web = web;
webServer.setShutdownHandler(server);
String url = webServer.addSession(conn);
try {
Server.openBrowser(url);
while (!webServer.isStopped()) {
Thread.sleep(1000);
}
} catch (Exception e) {
// ignore
}
}
use of org.h2.mvstore.db.TransactionStore.Transaction in project h2database by h2database.
the class TestLob method testRemovedAfterTimeout.
private void testRemovedAfterTimeout() throws Exception {
if (config.lazy) {
return;
}
deleteDb("lob");
final String url = getURL("lob;lob_timeout=50", true);
Connection conn = getConnection(url);
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, data clob)");
PreparedStatement prep = conn.prepareStatement("insert into test values(?, ?)");
prep.setInt(1, 1);
prep.setString(2, "aaa" + new String(new char[1024 * 16]).replace((char) 0, 'x'));
prep.execute();
prep.setInt(1, 2);
prep.setString(2, "bbb" + new String(new char[1024 * 16]).replace((char) 0, 'x'));
prep.execute();
ResultSet rs = stat.executeQuery("select * from test order by id");
rs.next();
Clob c1 = rs.getClob(2);
assertEquals("aaa", c1.getSubString(1, 3));
rs.next();
assertEquals("aaa", c1.getSubString(1, 3));
rs.close();
assertEquals("aaa", c1.getSubString(1, 3));
stat.execute("delete from test");
c1.getSubString(1, 3);
// wait until it times out
Thread.sleep(100);
// start a new transaction, to be sure
stat.execute("delete from test");
assertThrows(SQLException.class, c1).getSubString(1, 3);
conn.close();
}
use of org.h2.mvstore.db.TransactionStore.Transaction in project narayana by jbosstm.
the class TestCommitMarkableResourceReturnUnknownOutcomeFrom1PCCommit method testRMFAILAfterCommit.
@Test
public void testRMFAILAfterCommit() throws Exception {
jtaPropertyManager.getJTAEnvironmentBean().setNotifyCommitMarkableResourceRecoveryModuleOfCompleteBranches(false);
final JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:mem:JBTMDB;MVCC=TRUE;DB_CLOSE_DELAY=-1");
// Test code
Utils.createTables(dataSource.getConnection());
// We can't just instantiate one as we need to be using the
// same one as
// the transaction
// manager would have used to mark the transaction for GC
CommitMarkableResourceRecordRecoveryModule commitMarkableResourceRecoveryModule = null;
Vector recoveryModules = manager.getModules();
if (recoveryModules != null) {
Enumeration modules = recoveryModules.elements();
while (modules.hasMoreElements()) {
RecoveryModule m = (RecoveryModule) modules.nextElement();
if (m instanceof CommitMarkableResourceRecordRecoveryModule) {
commitMarkableResourceRecoveryModule = (CommitMarkableResourceRecordRecoveryModule) m;
} else if (m instanceof XARecoveryModule) {
XARecoveryModule xarm = (XARecoveryModule) m;
xarm.addXAResourceRecoveryHelper(new XAResourceRecoveryHelper() {
public boolean initialise(String p) throws Exception {
return true;
}
public XAResource[] getXAResources() throws Exception {
return new XAResource[] { xaResource };
}
});
}
}
}
javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
tm.begin();
Uid get_uid = ((TransactionImple) tm.getTransaction()).get_uid();
Connection localJDBCConnection = dataSource.getConnection();
localJDBCConnection.setAutoCommit(false);
nonXAResource = new JDBCConnectableResource(localJDBCConnection) {
@Override
public void commit(Xid arg0, boolean arg1) throws XAException {
super.commit(arg0, arg1);
throw new XAException(XAException.XAER_RMFAIL);
}
};
tm.getTransaction().enlistResource(nonXAResource);
xaResource = new SimpleXAResource();
tm.getTransaction().enlistResource(xaResource);
localJDBCConnection.createStatement().execute("INSERT INTO foo (bar) VALUES (1)");
tm.commit();
assertTrue(xaResource.wasCommitted());
Xid committed = ((JDBCConnectableResource) nonXAResource).getStartedXid();
assertNotNull(committed);
InputObjectState uids = new InputObjectState();
StoreManager.getRecoveryStore().allObjUids(new AtomicAction().type(), uids);
Uid uid = UidHelper.unpackFrom(uids);
assertTrue(uid.equals(get_uid));
// Belt and braces but we don't expect the CMR to be removed anyway as
// the RM is "offline"
manager.scan();
manager.scan();
// The recovery module has to perform lookups
new InitialContext().rebind("commitmarkableresource", dataSource);
assertTrue(commitMarkableResourceRecoveryModule.wasCommitted("commitmarkableresource", committed));
// This will complete the atomicaction
manager.scan();
StoreManager.getRecoveryStore().allObjUids(new AtomicAction().type(), uids);
uid = UidHelper.unpackFrom(uids);
assertTrue(uid.equals(Uid.nullUid()));
// This is when the CMR deletes are done due to ordering
manager.scan();
// of the recovery modules
assertFalse(commitMarkableResourceRecoveryModule.wasCommitted("commitmarkableresource", committed));
}
use of org.h2.mvstore.db.TransactionStore.Transaction in project ignite by apache.
the class GridReduceQueryExecutor method query.
/**
* @param schemaName Schema name.
* @param qry Query.
* @param keepBinary Keep binary.
* @param enforceJoinOrder Enforce join order of tables.
* @param timeoutMillis Timeout in milliseconds.
* @param cancel Query cancel.
* @param params Query parameters.
* @param parts Partitions.
* @param lazy Lazy execution flag.
* @return Rows iterator.
*/
public Iterator<List<?>> query(String schemaName, final GridCacheTwoStepQuery qry, boolean keepBinary, boolean enforceJoinOrder, int timeoutMillis, GridQueryCancel cancel, Object[] params, final int[] parts, boolean lazy) {
if (F.isEmpty(params))
params = EMPTY_PARAMS;
final boolean isReplicatedOnly = qry.isReplicatedOnly();
// Fail if all caches are replicated and explicit partitions are set.
for (int attempt = 0; ; attempt++) {
if (attempt != 0) {
try {
// Wait for exchange.
Thread.sleep(attempt * 10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CacheException("Query was interrupted.", e);
}
}
final long qryReqId = qryIdGen.incrementAndGet();
final ReduceQueryRun r = new ReduceQueryRun(qryReqId, qry.originalSql(), schemaName, h2.connectionForSchema(schemaName), qry.mapQueries().size(), qry.pageSize(), U.currentTimeMillis(), cancel);
AffinityTopologyVersion topVer = h2.readyTopologyVersion();
// Check if topology is changed while retrying on locked topology.
if (h2.serverTopologyChanged(topVer) && ctx.cache().context().lockedTopologyVersion(null) != null) {
throw new CacheException(new TransactionException("Server topology is changed during query " + "execution inside a transaction. It's recommended to rollback and retry transaction."));
}
List<Integer> cacheIds = qry.cacheIds();
Collection<ClusterNode> nodes;
// Explicit partition mapping for unstable topology.
Map<ClusterNode, IntArray> partsMap = null;
// Explicit partitions mapping for query.
Map<ClusterNode, IntArray> qryMap = null;
// Partitions are not supported for queries over all replicated caches.
if (parts != null) {
boolean replicatedOnly = true;
for (Integer cacheId : cacheIds) {
if (!cacheContext(cacheId).isReplicated()) {
replicatedOnly = false;
break;
}
}
if (replicatedOnly)
throw new CacheException("Partitions are not supported for replicated caches");
}
if (qry.isLocal())
nodes = singletonList(ctx.discovery().localNode());
else {
NodesForPartitionsResult nodesParts = nodesForPartitions(cacheIds, topVer, parts, isReplicatedOnly);
nodes = nodesParts.nodes();
partsMap = nodesParts.partitionsMap();
qryMap = nodesParts.queryPartitionsMap();
if (nodes == null)
// Retry.
continue;
assert !nodes.isEmpty();
if (isReplicatedOnly || qry.explain()) {
ClusterNode locNode = ctx.discovery().localNode();
// Always prefer local node if possible.
if (nodes.contains(locNode))
nodes = singletonList(locNode);
else {
// Select random data node to run query on a replicated data or
// get EXPLAIN PLAN from a single node.
nodes = singletonList(F.rand(nodes));
}
}
}
int tblIdx = 0;
final boolean skipMergeTbl = !qry.explain() && qry.skipMergeTable();
final int segmentsPerIndex = qry.explain() || isReplicatedOnly ? 1 : findFirstPartitioned(cacheIds).config().getQueryParallelism();
int replicatedQrysCnt = 0;
final Collection<ClusterNode> finalNodes = nodes;
for (GridCacheSqlQuery mapQry : qry.mapQueries()) {
GridMergeIndex idx;
if (!skipMergeTbl) {
GridMergeTable tbl;
try {
tbl = createMergeTable(r.connection(), mapQry, qry.explain());
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
idx = tbl.getMergeIndex();
fakeTable(r.connection(), tblIdx++).innerTable(tbl);
} else
idx = GridMergeIndexUnsorted.createDummy(ctx);
// If the query has only replicated tables, we have to run it on a single node only.
if (!mapQry.isPartitioned()) {
ClusterNode node = F.rand(nodes);
mapQry.node(node.id());
replicatedQrysCnt++;
// Replicated tables can have only 1 segment.
idx.setSources(singletonList(node), 1);
} else
idx.setSources(nodes, segmentsPerIndex);
idx.setPageSize(r.pageSize());
r.indexes().add(idx);
}
r.latch(new CountDownLatch(isReplicatedOnly ? 1 : (r.indexes().size() - replicatedQrysCnt) * nodes.size() * segmentsPerIndex + replicatedQrysCnt));
runs.put(qryReqId, r);
boolean release = true;
try {
cancel.checkCancelled();
if (ctx.clientDisconnected()) {
throw new CacheException("Query was cancelled, client node disconnected.", new IgniteClientDisconnectedException(ctx.cluster().clientReconnectFuture(), "Client node disconnected."));
}
List<GridCacheSqlQuery> mapQrys = qry.mapQueries();
if (qry.explain()) {
mapQrys = new ArrayList<>(qry.mapQueries().size());
for (GridCacheSqlQuery mapQry : qry.mapQueries()) mapQrys.add(new GridCacheSqlQuery("EXPLAIN " + mapQry.query()).parameterIndexes(mapQry.parameterIndexes()));
}
final boolean distributedJoins = qry.distributedJoins();
cancel.set(new Runnable() {
@Override
public void run() {
send(finalNodes, new GridQueryCancelRequest(qryReqId), null, false);
}
});
boolean retry = false;
// Always enforce join order on map side to have consistent behavior.
int flags = GridH2QueryRequest.FLAG_ENFORCE_JOIN_ORDER;
if (distributedJoins)
flags |= GridH2QueryRequest.FLAG_DISTRIBUTED_JOINS;
if (qry.isLocal())
flags |= GridH2QueryRequest.FLAG_IS_LOCAL;
if (qry.explain())
flags |= GridH2QueryRequest.FLAG_EXPLAIN;
if (isReplicatedOnly)
flags |= GridH2QueryRequest.FLAG_REPLICATED;
if (lazy && mapQrys.size() == 1)
flags |= GridH2QueryRequest.FLAG_LAZY;
GridH2QueryRequest req = new GridH2QueryRequest().requestId(qryReqId).topologyVersion(topVer).pageSize(r.pageSize()).caches(qry.cacheIds()).tables(distributedJoins ? qry.tables() : null).partitions(convert(partsMap)).queries(mapQrys).parameters(params).flags(flags).timeout(timeoutMillis).schemaName(schemaName);
if (send(nodes, req, parts == null ? null : new ExplicitPartitionsSpecializer(qryMap), false)) {
awaitAllReplies(r, nodes, cancel);
Object state = r.state();
if (state != null) {
if (state instanceof CacheException) {
CacheException err = (CacheException) state;
if (err.getCause() instanceof IgniteClientDisconnectedException)
throw err;
if (wasCancelled(err))
// Throw correct exception.
throw new QueryCancelledException();
throw new CacheException("Failed to run map query remotely." + err.getMessage(), err);
}
if (state instanceof AffinityTopologyVersion) {
retry = true;
// If remote node asks us to retry then we have outdated full partition map.
h2.awaitForReadyTopologyVersion((AffinityTopologyVersion) state);
}
}
} else
// Send failed.
retry = true;
Iterator<List<?>> resIter = null;
if (!retry) {
if (skipMergeTbl) {
resIter = new GridMergeIndexIterator(this, finalNodes, r, qryReqId, qry.distributedJoins());
release = false;
} else {
cancel.checkCancelled();
UUID locNodeId = ctx.localNodeId();
H2Utils.setupConnection(r.connection(), false, enforceJoinOrder);
GridH2QueryContext.set(new GridH2QueryContext(locNodeId, locNodeId, qryReqId, REDUCE).pageSize(r.pageSize()).distributedJoinMode(OFF));
try {
if (qry.explain())
return explainPlan(r.connection(), qry, params);
GridCacheSqlQuery rdc = qry.reduceQuery();
ResultSet res = h2.executeSqlQueryWithTimer(r.connection(), rdc.query(), F.asList(rdc.parameters(params)), // The statement will cache some extra thread local objects.
false, timeoutMillis, cancel);
resIter = new H2FieldsIterator(res);
} finally {
GridH2QueryContext.clearThreadLocal();
}
}
}
if (retry) {
if (Thread.currentThread().isInterrupted())
throw new IgniteInterruptedCheckedException("Query was interrupted.");
continue;
}
return new GridQueryCacheObjectsIterator(resIter, h2.objectContext(), keepBinary);
} catch (IgniteCheckedException | RuntimeException e) {
release = true;
U.closeQuiet(r.connection());
if (e instanceof CacheException) {
if (wasCancelled((CacheException) e))
throw new CacheException("Failed to run reduce query locally.", new QueryCancelledException());
throw (CacheException) e;
}
Throwable cause = e;
if (e instanceof IgniteCheckedException) {
Throwable disconnectedErr = ((IgniteCheckedException) e).getCause(IgniteClientDisconnectedException.class);
if (disconnectedErr != null)
cause = disconnectedErr;
}
throw new CacheException("Failed to run reduce query locally.", cause);
} finally {
if (release) {
releaseRemoteResources(finalNodes, r, qryReqId, qry.distributedJoins());
if (!skipMergeTbl) {
for (int i = 0, mapQrys = qry.mapQueries().size(); i < mapQrys; i++) // Drop all merge tables.
fakeTable(null, i).innerTable(null);
}
}
}
}
}
use of org.h2.mvstore.db.TransactionStore.Transaction in project h2database by h2database.
the class Session method setPreparedTransaction.
/**
* Commit or roll back the given transaction.
*
* @param transactionName the name of the transaction
* @param commit true for commit, false for rollback
*/
public void setPreparedTransaction(String transactionName, boolean commit) {
if (currentTransactionName != null && currentTransactionName.equals(transactionName)) {
if (commit) {
commit(false);
} else {
rollback();
}
} else {
ArrayList<InDoubtTransaction> list = database.getInDoubtTransactions();
int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK;
boolean found = false;
if (list != null) {
for (InDoubtTransaction p : list) {
if (p.getTransactionName().equals(transactionName)) {
p.setState(state);
found = true;
break;
}
}
}
if (!found) {
throw DbException.get(ErrorCode.TRANSACTION_NOT_FOUND_1, transactionName);
}
}
}
Aggregations