Puesto que la transacción de WebSphere eXtreme Scale termina antes de que se inicie la transacción de programa de fondo, es posible que se produzca un éxito falso de la transacción.
Si intenta insertar una entrada en una transacción de eXtreme Scale que no existe en la correlación de respaldo, pero existe en el programa de fondo, lo que genera una clave duplicada, la transacción de eXtreme Scale se realiza correctamente. Sin embargo, la transacción en la que la hebra de grabación diferida inserta el objeto en el programa de fondo falla con una excepción de clave duplicada.
Una actualización de este tipo, o cualquier otra actualización de programa de fondo con errores, es una actualización de grabación diferida con errores. Estas actualizaciones de grabación diferida con errores se almacenan en una correlación de actualizaciones de grabación diferida con errores. Esta correlación sirve como cola de sucesos para actualizaciones con errores. La clave de la actualización es un objeto Integer exclusivo, y el valor es una instancia del elemento FailedUpdateElement. La correlación anómala de actualización de escritura diferida se ha configurado con un desalojador, que desaloja los registros one hora después de que se hayan insertado. Por lo tanto, los registros de actualización anómala se perderán si no se recuperan en un plazo da una hora.
La API ObjectMap puede utilizarse para recuperar las entradas de correlación de actualizaciones de grabación diferida con errores. El nombre de la correlación de actualización de grabación diferida es: IBM_WB_FAILED_UPDATES_<nombre de la correlación>. Consulte la documentación de la API WriteBehindLoaderConstants para conocer los nombre de los prefijos de cada correlación de sistema de grabación diferida. Lo que aparece a continuación es un ejemplo.
proceso anómalo - código de ejemplo
ObjectMap failedMap = session.getMap(
WriteBehindLoaderConstants.WRITE_BEHIND_FAILED_UPDATES_MAP_PREFIX + "Employee");
Object key = null;
session.begin();
while(key = failedMap.getNextKey(ObjectMap.QUEUE_TIMEOUT_NONE)) {
FailedUpdateElement element = (FailedUpdateElement) failedMap.get(key);
Throwable throwable = element.getThrowable();
Object failedKey = element.getKey();
Object failedValue = element.getAfterImage();
failedMap.remove(key);
// Realizar alguna acción con la clave, el valor o la excepción.
}
session.commit();
Una llamada al método getNextKey funciona con una partición específica para cada transacción de eXtreme Scale. En un entorno distribuido, para obtener claves de todas las particiones, debe iniciar varias transacciones, como se muestra en el ejemplo siguiente:
obtención de claves de todas las particiones - código de ejemplo
ObjectMap failedMap = session.getMap(
WriteBehindLoaderConstants.WRITE_BEHIND_FAILED_UPDATES_MAP_PREFIX + "Employee");
while (true) {
session.begin();
Object key = null;
while(( key = failedMap.getNextKey(5000) )!= null ) {
FailedUpdateElement element = (FailedUpdateElement) failedMap.get(key);
Throwable throwable = element.getThrowable();
Object failedKey = element.getKey();
Object failedValue = element.getAfterImage();
failedMap.remove(key);
// Realizar alguna acción con la clave, el valor o la excepción.
}
Session.commit();
}
Es importante detectar y anotar cuándo falla una transacción de grabación diferida. Cada aplicación que utilice la grabación diferida debe implementar un vigilante que maneje las actualizaciones de grabación diferida con errores. Esto evitará que el sistema se quede sin memoria ya que los registros en la correlación de actualizaciones con errores no se desalojan porque se espera que la aplicación los maneje.
El código siguiente muestra cómo conectar dicho vigilante, o "dumper", que se debe añadir al XML de descriptor de ObjectGrid como en el fragmento de código.
<objectGrid name="Grid">
<bean id="ObjectGridEventListener" className="utils.WriteBehindDumper"/>
Puede ver el bean ObjectGridEventListener que se ha añadido, que es el vigilante de grabación diferida mencionado anteriormente. El vigilante interactúa en las correlaciones de todos los fragmentos primarios de una JVM en busca de los que tengan habilitada la grabación diferida. Si encuentra uno, intenta anotar hasta 100 actualizaciones con errores. Sigue vigilando un fragmento primario hasta que éste se mueve a otra JVM . Todas las aplicaciones que usan grabación diferida deben usar un vigilante similar a éste. De lo contrario, las Mäquinas virtuales Java se quedan sin memoria porque esta correlación de errores nunca se desaloja.
Si desea más información, consulte Ejemplo: Escribir una clase de volcador de grabación diferida.