diff --git metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java index bf2b5ed..db4b815 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java @@ -18,6 +18,10 @@ package org.apache.hadoop.hive.metastore; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.List; import java.util.Map; @@ -51,6 +55,14 @@ public interface RawStore extends Configurable { + /*** + * Annotation to skip retries + */ + @Target(value = ElementType.METHOD) + @Retention(value = RetentionPolicy.RUNTIME) + public @interface CanNotRetry { + } + public abstract void shutdown(); /** @@ -68,11 +80,13 @@ * * @return true or false */ + @CanNotRetry public abstract boolean commitTransaction(); /** * Rolls back the current transaction if it is active */ + @CanNotRetry public abstract void rollbackTransaction(); public abstract void createDatabase(Database db) diff --git metastore/src/java/org/apache/hadoop/hive/metastore/RetryingRawStore.java metastore/src/java/org/apache/hadoop/hive/metastore/RetryingRawStore.java index e0c354f..dcf97ec 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/RetryingRawStore.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/RetryingRawStore.java @@ -29,12 +29,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hive.common.JavaUtils; import org.apache.hadoop.hive.common.classification.InterfaceAudience; import org.apache.hadoop.hive.common.classification.InterfaceStability; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.api.MetaException; -import org.apache.hadoop.hive.metastore.hooks.JDOConnectionURLHook; import org.apache.hadoop.util.ReflectionUtils; @InterfaceAudience.Private @@ -46,7 +44,7 @@ private final RawStore base; private int retryInterval = 0; private int retryLimit = 0; - private MetaStoreInit.MetaStoreInitData metaStoreInitData = + private final MetaStoreInit.MetaStoreInitData metaStoreInitData = new MetaStoreInit.MetaStoreInitData(); private final int id; private final HiveConf hiveConf; @@ -132,12 +130,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl // Due to reflection, the jdo exception is wrapped in // invocationTargetException caughtException = (javax.jdo.JDOException) e.getCause(); - } - else + } else { throw e.getCause(); + } } - if (retryCount >= retryLimit) { + if (retryCount >= retryLimit || + (method.getAnnotation(RawStore.CanNotRetry.class) != null)) { throw caughtException; } diff --git metastore/src/test/org/apache/hadoop/hive/metastore/TestRawStoreTxn.java metastore/src/test/org/apache/hadoop/hive/metastore/TestRawStoreTxn.java new file mode 100644 index 0000000..0b87077 --- /dev/null +++ metastore/src/test/org/apache/hadoop/hive/metastore/TestRawStoreTxn.java @@ -0,0 +1,101 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hive.metastore; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +import javax.jdo.JDOException; + +import junit.framework.TestCase; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.conf.HiveConf; + +public class TestRawStoreTxn extends TestCase { + + public static class DummyRawStoreWithCommitError extends DummyRawStoreForJdoConnection { + private static int callCount = 0; + + @Override + /*** + * Throw exception on first try + */ + public boolean commitTransaction() { + callCount++; + if (callCount == 1 ) { + throw new JDOException ("Failed for call count " + callCount); + } else { + return true; + } + } + } + + private ObjectStore objStore; + private HiveConf hiveConf; + + @Override + protected void setUp() throws Exception { + super.setUp(); + hiveConf = new HiveConf(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /*** + * Check annotations of the restricted methods + * @throws Exception + */ + public void testCheckNoRetryMethods() throws Exception { + List nonExecMethods = + Arrays.asList("commitTransaction", "commitTransaction"); + + RawStore rawStore = RetryingRawStore.getProxy(hiveConf, new Configuration(hiveConf), + hiveConf.getVar(HiveConf.ConfVars.METASTORE_RAW_STORE_IMPL), 1); + for (Method rawStoreMethod : RawStore.class.getMethods()) { + if (nonExecMethods.contains(rawStoreMethod.getName())) { + assertNotNull(rawStoreMethod.getAnnotation(RawStore.CanNotRetry.class)); + } + } + } + + /*** + * Invoke commit and verify it doesn't get retried + * @throws Exception + */ + public void testVerifyNoRetryMethods() throws Exception { + hiveConf.setVar(HiveConf.ConfVars.METASTORECONNECTURLKEY, + DummyJdoConnectionUrlHook.newUrl);; + hiveConf.setVar(HiveConf.ConfVars.METASTORE_RAW_STORE_IMPL, + DummyRawStoreWithCommitError.class.getName()); + RawStore rawStore = RetryingRawStore.getProxy(hiveConf, new Configuration(hiveConf), + DummyRawStoreWithCommitError.class.getName(), 1); + try { + rawStore.commitTransaction(); + fail("Commit should fail due to no retry"); + } catch (JDOException e) { + // Excepted JDOException + } + } + +}