java - support - verificación de base de datos infinita de bucle
java in memory database (6)
Estoy usando JDBC, necesito verificar constantemente la base de datos contra cambios de valores.
Lo que tengo actualmente es un bucle infinito en ejecución, bucle interno que itera sobre valores cambiantes, y cada iteración se compara con la base de datos.
public void runInBG() { //this method called from another thread
while(true) {
while(els.hasElements()) {
Test el = (Test)els.next();
String sql = "SELECT * FROM Test WHERE id = ''" + el.getId() + "''";
Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
if(r != null) {
//do something
}
}
}
}
Creo que esta no es la mejor manera.
La otra manera que estoy pensando es al revés, para seguir iterando sobre la base de datos.
ACTUALIZAR
Gracias por los comentarios sobre temporizadores, pero no creo que va a resolver mi problema. Una vez que ocurre un cambio en la base de datos, necesito procesar los resultados casi instantáneamente contra los valores cambiantes ("els" del código de ejemplo).
Incluso si la base de datos no cambia, aún tiene que verificar constantemente contra los valores cambiantes.
ACTUALIZACIÓN 2
OK, para cualquier persona interesada en la respuesta, creo que tengo la solución ahora. Básicamente, la solución NO es usar la base de datos para esto. Cargar, actualizar, agregar, etc. ... solo lo que necesita de la base de datos a la memoria. De esta forma, no es necesario abrir y cerrar la base de datos constantemente, solo se ocupa de la base de datos cuando se realiza un cambio y se reflejan en la memoria y solo se ocupan de lo que está en la memoria en ese momento. Claro, esto requiere más memoria, pero el rendimiento es la clave absoluta aquí.
En cuanto a las respuestas periódicas de "temporizador", lo siento, pero esto no es correcto en absoluto. Nadie ha respondido con una razón por la cual el uso de temporizadores resolvería esta situación particular.
Pero gracias de nuevo por los comentarios, aún así fue útil.
ACTUALIZACIÓN 2
OK, para cualquier persona interesada en la respuesta, creo que tengo la solución ahora. Básicamente, la solución NO es usar la base de datos para esto. Cargar, actualizar, agregar, etc. ... solo lo que necesita de la base de datos a la memoria. De esta forma, no es necesario abrir y cerrar la base de datos constantemente, solo se ocupa de la base de datos cuando se realiza un cambio y se reflejan en la memoria y solo se ocupan de lo que está en la memoria en ese momento. Claro, esto requiere más memoria, pero el rendimiento es la clave absoluta aquí.
Como dijiste en el comentario anterior, si la aplicación controla las actualizaciones y las inserciones, entonces puedes crear un marco que notifique el hilo ''BG'' o el proceso sobre el cambio en la base de datos. La notificación puede realizarse a través de la red a través de JMS o intra VM utilizando un patrón de observador o notificaciones locales y remotas.
Puede tener un mensaje de notificación genérico como (puede ser una clase para notificación local o mensaje de texto para notificaciones remotas)
<Notification>
<Type>update/insert</Type>
<Entity>
<Name>Account/Customer</Name>
<Id>id</Id>
<Entity>
</Notification>
podrías usar un temporizador --->
Timer timer = new Timer("runInBG");
//Taking an instance of class contains your repeated method.
MyClass t = new MyClass();
timer.schedule(t, 0, 2000);
Para evitar un ''ciclo ocupado'', trataría de usar desencadenantes. H2 también es compatible con una API DatabaseEventListener , de esa manera no tendría que crear un disparador para cada tabla.
Esto no siempre funciona, por ejemplo, si usa una conexión remota.
Otra posibilidad sería usar ScheduledThreadPoolExecutor
.
Puede implementar un Runnable
contenga su lógica y registrarlo en el ScheduledExecutorService
siguiente manera:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);
El código anterior crea un ScheduledThreadPoolExecutor
con 10 subprocesos en su grupo, y tendría un Runnable
registrado que se ejecutará en un período de 5 segundos comenzando inmediatamente.
Para programar su ejecución, puede usar:
Crea y ejecuta una acción periódica que se habilita primero después del retraso inicial dado, y posteriormente con el período dado; es decir, las ejecuciones comenzarán después de InitialDelay luego InitialDelay + period, luego InitialDelay + 2 * period, y así sucesivamente.
Crea y ejecuta una acción periódica que se habilita primero después de la demora inicial dada, y posteriormente con la demora dada entre la finalización de una ejecución y el comienzo de la siguiente.
Y aquí puede ver las ventajas de ThreadPoolExecutor
, para ver si se ajusta a sus necesidades. Aconsejo esta pregunta: Java Timer vs ExecutorService? también para tomar una buena decisión.