diff --git metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java index b0fa836..cc1f346 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hive.metastore.DatabaseProduct; import org.apache.hadoop.hive.metastore.HouseKeeperService; import org.apache.hadoop.hive.metastore.Warehouse; +import org.apache.thrift.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.dbcp.PoolingDataSource; @@ -515,17 +516,19 @@ public OpenTxnsResponse openTxns(OpenTxnRequest rqst) throws MetaException { } } - public void abortTxn(AbortTxnRequest rqst) throws NoSuchTxnException, MetaException { + public void abortTxn(AbortTxnRequest rqst) throws NoSuchTxnException, MetaException, TxnAbortedException { long txnid = rqst.getTxnid(); try { Connection dbConn = null; + Statement stmt = null; try { lockInternal(); dbConn = getDbConn(Connection.TRANSACTION_READ_COMMITTED); if (abortTxns(dbConn, Collections.singletonList(txnid), true) != 1) { LOG.debug("Going to rollback"); dbConn.rollback(); - throw new NoSuchTxnException("No such transaction " + JavaUtils.txnIdToString(txnid)); + stmt = dbConn.createStatement(); + ensureValidTxn(dbConn, txnid, stmt); } LOG.debug("Going to commit"); @@ -537,7 +540,7 @@ public void abortTxn(AbortTxnRequest rqst) throws NoSuchTxnException, MetaExcept throw new MetaException("Unable to update transaction database " + StringUtils.stringifyException(e)); } finally { - closeDbConn(dbConn); + close(null, stmt, dbConn); unlockInternal(); } } catch (RetryException e) { diff --git metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnStore.java metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnStore.java index 3c06517..dcddc59 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnStore.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/txn/TxnStore.java @@ -97,7 +97,7 @@ * @throws NoSuchTxnException * @throws MetaException */ - public void abortTxn(AbortTxnRequest rqst) throws NoSuchTxnException, MetaException; + public void abortTxn(AbortTxnRequest rqst) throws NoSuchTxnException, MetaException, TxnAbortedException; /** * Abort (rollback) a list of transactions in one request. diff --git ql/src/test/org/apache/hadoop/hive/metastore/txn/TestTxnHandler.java ql/src/test/org/apache/hadoop/hive/metastore/txn/TestTxnHandler.java index dbe1ce8..11cedb9 100644 --- ql/src/test/org/apache/hadoop/hive/metastore/txn/TestTxnHandler.java +++ ql/src/test/org/apache/hadoop/hive/metastore/txn/TestTxnHandler.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.hive.metastore.txn; +import org.apache.hadoop.hive.common.JavaUtils; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.api.AbortTxnRequest; import org.apache.hadoop.hive.metastore.api.CheckLockRequest; @@ -162,6 +163,36 @@ public void testAbortTxn() throws Exception { saw[tid.intValue()] = true; } for (int i = 1; i < saw.length; i++) assertTrue(saw[i]); + txnHandler.commitTxn(new CommitTxnRequest(2)); + boolean gotException = false; + try { + txnHandler.abortTxn(new AbortTxnRequest(1)); + } + catch(TxnAbortedException ex) { + gotException = true; + Assert.assertEquals("Transaction " + JavaUtils.txnIdToString(1) + " already aborted", ex.getMessage()); + } + Assert.assertTrue(gotException); + gotException = false; + try { + txnHandler.abortTxn(new AbortTxnRequest(2)); + } + catch(NoSuchTxnException ex) { + gotException = true; + //if this wasn't an empty txn, we'd get a better msg + //Assert.assertEquals("Transaction " + JavaUtils.txnIdToString(2) + " already committed.", ex.getMessage()); + Assert.assertEquals("No such transaction " + JavaUtils.txnIdToString(2), ex.getMessage()); + } + Assert.assertTrue(gotException); + gotException = false; + try { + txnHandler.abortTxn(new AbortTxnRequest(3)); + } + catch(NoSuchTxnException ex) { + gotException = true; + Assert.assertEquals("No such transaction " + JavaUtils.txnIdToString(3), ex.getMessage()); + } + Assert.assertTrue(gotException); } @Test