代码之家  ›  专栏  ›  技术社区  ›  Darren Willows

Java 7 Pass方法作为通用SQL死锁检查的参数

  •  3
  • Darren Willows  · 技术社区  · 7 年前

    在Java 7中,是否可以将该方法作为参数传递。

    该方法将被调用并封装在do中,以检查sql死锁并重试。

    当表上有锁时,我试图用一种通用的方法来处理死锁,因为目前有数千个插入和更新来复制它。目前它只查找SQLException,但可以将其更改为SQLException的getErrorCode和目标ER\u LOCK\u DEADLOCK。

    下面的代码只是我试图实现的一个示例:

    public void Object1Insert(Object1 object1){
        genericSQLRetry(insertObject1(object1));
    }
    
    public void Object2Insert(Object2 object2){
        genericSQLRetry(insertObject2(object2));
    }
    
    public void genericSQLRetry({method}){
        int retries = 5;
        boolean isException = false;
      do{
        try {
            isException = false;
            retries--;
            //Invoke method
            {method}
        }catch (SQLException e){
            isException = true;
        }
    
        if (isException & retries > 0){
            //getRandomSleep would be between 750-1250ms. This is to stop multiple retries at the same time.
            Thread.sleep(getRandomSleep());
        }
      }while (isException == true && retries > 0);
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   T.J. Crowder    7 年前

    没有。这就是为什么Java 8添加了lambda(包括方法引用)和功能接口。

    但您可以在接口中定义方法,在调用类(可能是您在本地实例化的匿名类)中实现该接口,在中接受该接口 genericSQLRetry ,并对收到的实例调用该方法。

    Runnable (这是他们在Java 8中为lambdas所做的,没有参数和返回值),并且:

    public void Object1Insert(final Object1 object1) {
        genericSQLRetry(new Runnable {
            public void run() {
                insertObject1(object1);
            }
        });
    }
    
    public void Object2Insert(Object2 object2) {
        genericSQLRetry(new Runnable {
            public void run() {
                insertObject2(object2);
            }
        });
    }
    
    public void genericSQLRetry(Runnable retryable) {
        int retries = 5;
        boolean isException = false;
        do {
            try {
                isException = false;
                retries--;
                //Invoke method
                retryable.run();
            }
            catch (SQLException e) {
                isException = true;
            }
    
            if (isException & retries > 0) {
                //getRandomSleep would be between 750-1250ms. This is to stop multiple retries at the same time.
                Thread.sleep(getRandomSleep());
            }
        } while (isException == true && retries > 0);
    }
    

    interface Retryable {
        void retry() {
        }
    }
    

    然后使用 Retryable 可运行

        2
  •  1
  •   Pfeiffer    7 年前

    是的,如果使用反射,在某种程度上可以将方法作为参数传递。

    您将传递一个具有正确方法名称和用法的字符串

    Method method = this.getClass().getDeclaredMethod("methodName", new Class[]});
    

    method.invoke(object)
    

    可以找到有关反射的更多信息 here here 包括为什么你应该 avoid using it .