Utilice el plug-in OptimisticCallback para personalizar las operaciones de creación de versiones y comparación de los objetos de la memoria caché cuando se utiliza la estrategia de bloqueo optimista.
Puede proporcionar un objeto de devolución de llamada optimista conectable que implementa la interfaz com.ibm.websphere.objectgrid.plugins.OptimisticCallback. En el caso de correlaciones de entidad, se configura automáticamente un plug-in OptimisticCallback de alto rendimiento.
Utilice la interfaz OptimisticCallback para proporcionar operaciones de comparación optimista para los valores de una correlación. Es necesario un plug-in OptimisticCallback al utilizar la estrategia de bloqueo optimista. El producto proporciona una implementación de OptimisticCallback predeterminada. Sin embargo, por lo general, la aplicación debe conectar su propia implementación de la interfaz OptimisticCallback.
public interface Employee
{
// Número de secuencia utilizado para la creación de versiones optimista.
public long getSequenceNumber();
public void setSequenceNumber(long newSequenceNumber);
// Otros métodos get/set para otros campos del objeto Employee.
}
En este ejemplo, el cargador sabe que puede utilizar el método getSequenceNumber para obtener la información de la versión actual para un objeto de valor Employee. El cargador incrementa el valor devuelto para generar un nuevo número de versión antes de actualizar el almacenamiento persistente con el nuevo valor Employee. Para un cargador JDBC (Java DataBase Connectivity), se utiliza el número de secuencia actual de la cláusula WHERE de una sentencia de SQL UPDATE sobrecualificada, y utiliza el nuevo número de secuencia generado para establecer la columna de número de secuencia en el nuevo valor de número de secuencia. Otra posibilidad es que el cargador utilice una función, que proporciona el programa de fondo, que actualiza automáticamente una columna oculta que puede utilizarse para la creación de versiones optimista.
En algunas situaciones, posiblemente se puede utilizar un procedimiento almacenado o un desencadenante que ayuda a mantener una columna que aloja información sobre la creación de versiones. Si el cargador utiliza una de estas técnicas para mantener la información de la creación de versiones optimista, la aplicación no necesita proporcionar una implementación OptimisticCallback. Se puede utilizar la implementación predeterminada de OptimisticCallback en este escenario porque el cargador puede manejar la creación de versiones optimista sin la ayuda de un objeto OptimisticCallback.
Las entidades se almacenan en ObjectGrid mediante objetos de tuple. El comportamiento predeterminado de la implementación OptimisticCallback es similar al comportamiento para las correlaciones sin entidades. Sin embargo, el campo de versión de la entidad se identifica a través del uso de la anotación @Version o el atributo de versión en el archivo XML de descriptor de la entidad.
El atributo de versión puede ser de uno de los tipos siguientes: int, Integer, short, Short, long, Long o java.sql.Timestamp. Una entidad sólo debe tener un atributo de versión definido. Establezca el atributo de versión sólo durante la construcción. Después de persistir la entidad, el valor del atributo de versión no se debe modificar.
Si no se configura el atributo de versión y se utiliza la estrategia de bloqueo optimista, se crea una versión implícitamente de todo el tuple mediante el estado completo del tuple, que es más costoso.
@Entity
public class Employee
{
private long sequence;
// Número de secuencia utilizado para la creación de versiones optimista.
@Version
public long getSequenceNumber() {
return sequence;
}
public void setSequenceNumber(long newSequenceNumber) {
this.sequence = newSequenceNumber;
}
// Otros métodos get/set para otros campos del objeto Employee.
}
Un plug-in OptimisticCallback debe implementar la interfaz OptimisticCallback y seguir los convenios comunes de plug-in de ObjectGrid. Consulte Interfaz OptimisticCallback si desea más información.
En la lista siguiente se proporciona una descripción o consideración de cada uno de los métodos de la interfaz OptimisticCallback:
Este valor especial es devuelto por el método getVersionedObjectForValue si la implementación de OptimisticCallback no requiere ninguna comprobación de versiones. La implementación del plug-in incorporada de la clase com.ibm.websphere.objectgrid.plugins.builtins.NoVersioningOptimisticCallback utiliza este valor porque la creación de versiones está inhabilitada cuando se especifica esta implementación de plug-in.
El método getVersionedObjectForValue podría devolver una copia del valor o un atributo del valor que se puede utilizar para la creación de versiones. Este método se llama siempre que se asocia un objeto con una transacción. Si no se conecta ningún cargador a la correlación de respaldo, ésta utiliza este valor durante la fase de confirmación para llevar a cabo una comparación de versiones optimista. La correlación de respaldo utiliza la comparación de versiones optimista para asegurarse de que la versión no ha cambiado desde la primera que vez que esta transacción accedió a la entrada de la correlación que fue modificada por esta transacción. Si otra transacción hubiera modificado la versión de esta entrada de correlación, se produciría una anomalía en la comparación de versiones y la correlación de respaldo mostraría una excepción OptimisticCollisionException que forzaría la retrotracción de la transacción. Si hay un cargador conectado, la correlación de respaldo no utiliza la información de creación de versiones optimista. En su lugar, el cargador deberá realizar una comparación de versiones optimista y actualizar la información de la creación de versiones cuando sea necesario. El cargador suelte obtener el objeto de versiones inicial del LogElement pasado al método batchUpdate del cargador, que se llama cuando se produce una operación de vaciado o se confirma una transacción.
public Object getVersionedObjectForValue(Object value)
{
if (value == null)
{
return null;
}
else
{
Employee emp = (Employee) value;
return new Long( emp.getSequenceNumber() );
}
}
Tal como se demuestra en el ejemplo anterior, se devuelve el atributo sequenceNumber en un objeto java.lang.Long tal como espera el cargador, que implica que la misma persona que escribió el cargador, también escribió la implementación de EmployeeOptimisticCallbackImpl, o bien trabajó estrechamente con la persona que implementó el método EmployeeOptimisticCallbackImpl, por ejemplo, acordó el valor devuelto por el método getVersionedObjectForValue. El plug-in predeterminado OptimisticCallback devuelve el valor especial NULL_OPTIMISTIC_VERSION como el objeto de versión.
public void updateVersionedObjectForValue(Object value)
{
if ( value != null )
{
Employee emp = (Employee) value;
long next = emp.getSequenceNumber() + 1;
emp.updateSequenceNumber( next );
}
}
Tal como se demuestra en el ejemplo anterior, el atributo sequenceNumber se incrementa por uno, de forma que la próxima vez que se llama al método getVersionedObjectForValue, el valor java.lang.Long devuelto tiene un valor largo que es el valor del número de secuencia original más uno, por ejemplo, es el valor de la siguiente versión para esta instancia de empleado. Este ejemplo implica que la misma persona que escribió el cargador escribió EmployeeOptimisticCallbackImpl o bien trabajó estrechamente con la persona que implementó EmployeeOptimisticCallbackImpl.
Este método escribe el valor con versión en la corriente especificada. En función de la implementación, el valor con versión puede utilizarse para identificar colisiones de actualización optimista. En algunas implementaciones, el valor con versión es una copia del valor original. Otras implementaciones podrían tener un número de secuencia o algún otro objeto para indicar la versión del valor. Puesto que la implementación real se desconoce, este método se proporciona para realizar la serialización apropiada. La implementación predeterminada llama al método writeObject.
Este método toma la versión serializada del valor con versión y devuelve el objeto de valor con versión real. En función de la implementación, el valor con versión puede utilizarse para identificar colisiones de actualización optimista. En algunas implementaciones, el valor con versión es una copia del valor original. Otras implementaciones podrían tener un número de secuencia o algún otro objeto para indicar la versión del valor. Puesto que se desconoce la implementación real, este método se proporciona para realizar la deserialización apropiada. La implementación predeterminada llama al método readObject.
Dispone de dos enfoques para añadir un objeto OptimisticCallback proporcionado por la aplicación en la configuración de BackingMap: configuración de XML y configuración mediante programa.
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
import com.ibm.websphere.objectgrid.ObjectGridManager;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.BackingMap;
ObjectGridManager ogManager = ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid og = ogManager.createObjectGrid( "grid1" );
BackingMap bm = dg.defineMap("employees");
EmployeeOptimisticCallbackImpl cb = new EmployeeOptimisticCallbackImpl();
bm.setOptimisticCallback( cb );
<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
xmlns="http://ibm.com/ws/objectgrid/config">
<objectGrids>
<objectGrid name="grid1">
<backingMap name="employees" pluginCollectionRef="employees" lockStrategy="OPTIMISTIC" />
</objectGrid>
</objectGrids>
<backingMapPluginCollections>
<backingMapPluginCollection id="employees">
<bean id="OptimisticCallback" className="com.xyz.EmployeeOptimisticCallbackImpl" />
</backingMapPluginCollection>
</backingMapPluginCollections>
</objectGridConfig>