Java 7 将方法作为参数传递给通用 SQL 死锁检查
Java 7 Pass Method as Paramater for generic SQL Deadlock check
在 Java 7 中是否可以将方法作为参数传递。
该方法将被调用并封装在 do while 中以检查 sql 死锁并重试。
当 table 上有锁时,我正在尝试制定一种处理死锁的通用方法,因为目前有数千个插入和更新来复制它。目前它只会寻找 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);
}
In Java 7 is it possible pass the method as a paramater.
没有。这就是为什么 Java 8 添加了 lambda(包括方法引用)和功能接口。
但是您可以在接口中定义方法,在调用 class(es) 中实现该接口(可能是您在本地实例化的匿名接口),在 genericSQLRetry
中接受该接口,然后调用您收到的实例上的方法。
在您的情况下,您可以重新使用 Runnable
(这是他们在 Java 8 中对没有参数且没有 return 值的 lambda 所做的),并且:
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
而不是 Runnable
。
是的,如果你使用反射,你可以在某种程度上将方法作为参数传递。
您将传递一个具有正确方法名称的字符串并使用
Method method = this.getClass().getDeclaredMethod("methodName", new Class[]});
然后使用:
method.invoke(object)
可以找到更多关于反射的信息here and here including why you should avoid using it。
在 Java 7 中是否可以将方法作为参数传递。
该方法将被调用并封装在 do while 中以检查 sql 死锁并重试。
当 table 上有锁时,我正在尝试制定一种处理死锁的通用方法,因为目前有数千个插入和更新来复制它。目前它只会寻找 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);
}
In Java 7 is it possible pass the method as a paramater.
没有。这就是为什么 Java 8 添加了 lambda(包括方法引用)和功能接口。
但是您可以在接口中定义方法,在调用 class(es) 中实现该接口(可能是您在本地实例化的匿名接口),在 genericSQLRetry
中接受该接口,然后调用您收到的实例上的方法。
在您的情况下,您可以重新使用 Runnable
(这是他们在 Java 8 中对没有参数且没有 return 值的 lambda 所做的),并且:
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
而不是 Runnable
。
是的,如果你使用反射,你可以在某种程度上将方法作为参数传递。
您将传递一个具有正确方法名称的字符串并使用
Method method = this.getClass().getDeclaredMethod("methodName", new Class[]});
然后使用:
method.invoke(object)
可以找到更多关于反射的信息here and here including why you should avoid using it。