@Override public long openTxn(Context ctx, String user) throws LockException { return openTxn(ctx, user, 0); }
@VisibleForTesting long openTxn(Context ctx, String user, long delay) throws LockException { /*Q: why don't we lock the snapshot here??? Instead of having client make an explicit call whenever it chooses A: If we want to rely on locks for transaction scheduling we must get the snapshot after lock acquisition. Relying on locks is a pessimistic strategy which works better under high contention.*/ init(); getLockManager(); if(isTxnOpen()) { throw new LockException("Transaction already opened. " + JavaUtils.txnIdToString(txnId)); } try { txnId = getMS().openTxn(user); stmtId = 0; numStatements = 0; tableWriteIds.clear(); isExplicitTransaction = false; startTransactionCount = 0; LOG.info("Opened " + JavaUtils.txnIdToString(txnId)); ctx.setHeartbeater(startHeartbeat(delay)); return txnId; } catch (TException e) { throw new LockException(e, ErrorMsg.METASTORE_COMMUNICATION_FAILED); } }
@Test public void testExceptions() throws Exception { addPartitionOutput(newTable(true), WriteEntity.WriteType.INSERT); QueryPlan qp = new MockQueryPlan(this, HiveOperation.QUERY); ((DbTxnManager) txnMgr).openTxn(ctx, "NicholasII", HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS) * 2); Thread.sleep(HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS)); runReaper(); LockException exception = null; try { txnMgr.commitTxn(); } catch(LockException ex) { exception = ex; } Assert.assertNotNull("Expected exception1", exception); Assert.assertEquals("Wrong Exception1", ErrorMsg.TXN_ABORTED, exception.getCanonicalErrorMsg()); exception = null; ((DbTxnManager) txnMgr).openTxn(ctx, "AlexanderIII", HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS) * 2); Thread.sleep(HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS)); runReaper();//this will abort the txn TxnStore txnHandler = TxnUtils.getTxnStore(conf); GetOpenTxnsInfoResponse txnsInfo = txnHandler.getOpenTxnsInfo(); assertEquals(2, txnsInfo.getTxn_high_water_mark()); assertEquals(2, txnsInfo.getOpen_txns().size()); Assert.assertEquals(TxnState.ABORTED, txnsInfo.getOpen_txns().get(1).getState()); txnMgr.rollbackTxn();//this is idempotent }
((DbTxnManager) txnMgr).openTxn(ctx, "tom", HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS) / 2); txnMgr.acquireLocks(qp, ctx, "tom"); ((DbTxnManager) txnMgr).openTxn(ctx, "jerry", HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS) * 2); txnMgr.acquireLocks(qp, ctx, "jerry"); Thread.sleep(HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_TXN_TIMEOUT, TimeUnit.MILLISECONDS));