जावा 7 में यह संभव है कि विधि को एक पैरामीटर के रूप में पास किया जाए।

विधि को लागू किया जाएगा और एसक्यूएल गतिरोध की जांच करने और पुनः प्रयास करने के लिए थोड़ी देर में इनकैप्सुलेट किया जाएगा।

मैं टेबल पर लॉक होने पर डेडलॉक्स को संभालने का एक सामान्य तरीका बनाने की कोशिश कर रहा हूं, क्योंकि वर्तमान में इसे दोहराने के लिए हजारों प्रविष्टियां और अपडेट हैं। वर्तमान में यह केवल SQLException की तलाश करेगा लेकिन इसे SQLException के getErrorCode और लक्ष्य ER_LOCK_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);
}
3
Darren Willows 12 अगस्त 2017, 17:16

1 उत्तर

सबसे बढ़िया उत्तर

जावा 7 में यह संभव है कि विधि को एक पैरामीटर के रूप में पास किया जाए।

नहीं, यही कारण है कि जावा 8 लैम्ब्डा (विधि संदर्भों सहित) और कार्यात्मक इंटरफेस जोड़ता है।

लेकिन आप इंटरफ़ेस में विधि को परिभाषित कर सकते हैं, उस इंटरफ़ेस को कॉलिंग क्लास (एस) में लागू कर सकते हैं (शायद अनाम जिन्हें आप स्थानीय रूप से तत्काल करते हैं), उस इंटरफ़ेस को genericSQLRetry में स्वीकार करें, और आपको प्राप्त होने वाले उदाहरण पर विधि को कॉल करें।

आपके मामले में, आप Runnable का पुन: उपयोग कर सकते हैं (जो उन्होंने जावा 8 में लैम्बडास के लिए बिना किसी पैरामीटर और बिना रिटर्न वैल्यू के किया था), और:

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() {
    }
}

फिर Runnable के बजाय Retryable का उपयोग करें।

2
T.J. Crowder 12 अगस्त 2017, 17:27