use of org.apache.hadoop.hive.metastore.api.NoSuchLockException in project hive by apache.
the class TestTxnHandler method testHeartbeatLock.
@Test
public void testHeartbeatLock() throws Exception {
conf.setTimeVar(HiveConf.ConfVars.HIVE_TXN_TIMEOUT, 1, TimeUnit.SECONDS);
HeartbeatRequest h = new HeartbeatRequest();
LockComponent comp = new LockComponent(LockType.EXCLUSIVE, LockLevel.DB, "mydb");
comp.setTablename("mytable");
comp.setPartitionname("mypartition");
comp.setOperationType(DataOperationType.NO_TXN);
List<LockComponent> components = new ArrayList<LockComponent>(1);
components.add(comp);
LockRequest req = new LockRequest(components, "me", "localhost");
LockResponse res = txnHandler.lock(req);
assertTrue(res.getState() == LockState.ACQUIRED);
h.setLockid(res.getLockid());
for (int i = 0; i < 30; i++) {
try {
txnHandler.heartbeat(h);
} catch (NoSuchLockException e) {
fail("Told there was no lock, when the heartbeat should have kept it.");
}
}
}
use of org.apache.hadoop.hive.metastore.api.NoSuchLockException in project hive by apache.
the class TestTxnHandler method testCheckLockTxnAborted.
@Test
public void testCheckLockTxnAborted() throws Exception {
// Test that when a transaction is aborted, the heartbeat fails
long txnid = openTxn();
LockComponent comp = new LockComponent(LockType.SHARED_WRITE, LockLevel.DB, "mydb");
comp.setTablename("mytable");
comp.setPartitionname("mypartition");
comp.setOperationType(DataOperationType.DELETE);
List<LockComponent> components = new ArrayList<LockComponent>(1);
components.add(comp);
LockRequest req = new LockRequest(components, "me", "localhost");
req.setTxnid(txnid);
LockResponse res = txnHandler.lock(req);
long lockid = res.getLockid();
txnHandler.abortTxn(new AbortTxnRequest(txnid));
try {
// This will throw NoSuchLockException (even though it's the
// transaction we've closed) because that will have deleted the lock.
txnHandler.checkLock(new CheckLockRequest(lockid));
fail("Allowed to check lock on aborted transaction.");
} catch (NoSuchLockException e) {
}
}
use of org.apache.hadoop.hive.metastore.api.NoSuchLockException in project hive by apache.
the class TxnHandler method heartbeatLock.
/**
* Heartbeats on the lock table. This commits, so do not enter it with any state.
* Should not be called on a lock that belongs to transaction.
*/
private void heartbeatLock(Connection dbConn, long extLockId) throws NoSuchLockException, SQLException, MetaException {
// If the lock id is 0, then there are no locks in this heartbeat
if (extLockId == 0)
return;
Statement stmt = null;
try {
stmt = dbConn.createStatement();
long now = getDbTime(dbConn);
String s = "update HIVE_LOCKS set hl_last_heartbeat = " + now + " where hl_lock_ext_id = " + extLockId;
LOG.debug("Going to execute update <" + s + ">");
int rc = stmt.executeUpdate(s);
if (rc < 1) {
LOG.debug("Going to rollback");
dbConn.rollback();
throw new NoSuchLockException("No such lock: " + JavaUtils.lockIdToString(extLockId));
}
LOG.debug("Going to commit");
dbConn.commit();
} finally {
closeStmt(stmt);
}
}
use of org.apache.hadoop.hive.metastore.api.NoSuchLockException in project hive by apache.
the class TxnHandler method checkLock.
/**
* Why doesn't this get a txnid as parameter? The caller should either know the txnid or know there isn't one.
* Either way getTxnIdFromLockId() will not be needed. This would be a Thrift change.
*
* Also, when lock acquisition returns WAITING, it's retried every 15 seconds (best case, see DbLockManager.backoff(),
* in practice more often)
* which means this is heartbeating way more often than hive.txn.timeout and creating extra load on DB.
*
* The clients that operate in blocking mode, can't heartbeat a lock until the lock is acquired.
* We should make CheckLockRequest include timestamp or last request to skip unnecessary heartbeats. Thrift change.
*
* {@link #checkLock(java.sql.Connection, long)} must run at SERIALIZABLE (make sure some lock we are checking
* against doesn't move from W to A in another txn) but this method can heartbeat in
* separate txn at READ_COMMITTED.
*
* Retry-by-caller note:
* Retryable because {@link #checkLock(Connection, long)} is
*/
@Override
@RetrySemantics.SafeToRetry
public LockResponse checkLock(CheckLockRequest rqst) throws NoSuchTxnException, NoSuchLockException, TxnAbortedException, MetaException {
try {
Connection dbConn = null;
long extLockId = rqst.getLockid();
try {
lockInternal();
dbConn = getDbConn(Connection.TRANSACTION_READ_COMMITTED);
// Heartbeat on the lockid first, to assure that our lock is still valid.
// Then look up the lock info (hopefully in the cache). If these locks
// are associated with a transaction then heartbeat on that as well.
LockInfo info = getTxnIdFromLockId(dbConn, extLockId);
if (info == null) {
throw new NoSuchLockException("No such lock " + JavaUtils.lockIdToString(extLockId));
}
if (info.txnId > 0) {
heartbeatTxn(dbConn, info.txnId);
} else {
heartbeatLock(dbConn, extLockId);
}
// extra heartbeat is logically harmless, but ...
return checkLock(dbConn, extLockId);
} catch (SQLException e) {
LOG.debug("Going to rollback");
rollbackDBConn(dbConn);
checkRetryable(dbConn, e, "checkLock(" + rqst + " )");
throw new MetaException("Unable to update transaction database " + JavaUtils.lockIdToString(extLockId) + " " + StringUtils.stringifyException(e));
} finally {
closeDbConn(dbConn);
unlockInternal();
}
} catch (RetryException e) {
return checkLock(rqst);
}
}
Aggregations