Verwenden Sie das OptimisticCallback-Plug-in, um Versionssteuerungs- und Vergleichsoperationen für Cacheobjekte anzupassen, wenn Sie die optimistische Sperrstrategie verwenden.
Sie können ein Plug-in-fähiges optimistisches Callback-Objekt bereitstellen, das die Schnittstelle "com.ibm.websphere.objectgrid.plugins.OptimisticCallback" implementiert. Für Entitäts-Maps wird automatisch ein OptimisticCallback-Plug-in mit hoher Leistung konfiguriert.
Verwenden Sie die Schnittstelle "OptimisticCallback" für die Unterstützung optimistischer Vergleichsoperationen für die Werte einer Map. Ein OptimisticCallback-Plug-in ist erforderlich, wenn Sie die optimistische Sperrstrategie verwenden. Das Produkt stellt eine Standardimplementierung der Schnittstelle "OptimisticCallback" bereit. Gewöhnlich muss die Anwendung eine eigene Implementierung der Schnittstelle "OptimisticCallback" integrieren.
public interface Employee
{
// Für die optimistische Versionssteuerung verwendete Folgenummer.
public long getSequenceNumber();
public void setSequenceNumber(long newSequenceNumber);
// Weitere get/set-Methoden für andere Felder des Employee-Objekts.
}
In diesem Beispiel weiß der Loader, dass er die Methode "getSequenceNumber" verwenden kann, um die aktuellen Versionsinformationen für ein Employee-Wertobjekt abzurufen. Der Loader erhöht den zurückgegebenen Wert um eins, um eine neue Versionsnummer zu generieren, bevor er den persistenten Speicher mit dem neuen Employee-Wert aktualisiert. Für einen JDBC-Loader (Java Database Connectivity) wird die aktuelle Folgenummer in der WHERE-Klausel einer überqualifizierten SQL-Anweisung "UPDATE" verwendet. Der Loader verwendet die neu generierte Folgenummer, um die Folgenummernspalte auf den neuen Folgenummernwert zu setzen. Eine weitere Möglichkeit ist die, dass der Loader eine vom Back-End bereitgestellte Funktion verwendet, die eine verdeckte Spalte, die für die optimistische Versionssteuerung verwendet werden kann, automatisch aktualisiert.
In manchen Fällen kann unter Umständen eine gespeicherte Prozedur oder ein Trigger verwendet werden, um eine Spalte zu verwalten, die Informationen zur Versionssteuerung enthält. Wenn der Loader eine dieser Techniken für die Verwaltung der Informationen zur optimistischen Versionssteuerung verwendet, muss die Anwendung keine eigene OptimisticCallback-Implementierung bereitstellen. Die OptimisticCallback-Standardimplementierung kann in diesem Szenario verwendet werden, weil der Loader die optimistische Versioningssteuerung ohne Hilfe eines OptimisticCallback-Objekts durchführen kann.
Entitäten werden im ObjectGrid mit Hilfe von Tupelobjekten gespeichert. Die OptimisticCallback-Standardimplementierung gleicht dem Verhalten bei Maps, die keine Entitäts-Maps sind. Das Versionsfeld in der Entität wird jedoch mit der Annotation "@Version" bzw. dem Versionsattribut in der XML-Deskriptordatei der Entität angegeben.
Die gültigen Datentypen für das Versionsattribut sind int, Integer, short, Short, long, Long und java.sql.Timestamp. Für eine Entität darf nur ein einziges Versionsattribut definiert werden. Das Versionsattribut darf nur während der Erstellung definiert werden. Sobald die Entität als persistent definiert wird, darf der Wert des Versionsattributs nicht mehr geändert werden.
Wenn kein Versionsattribut konfiguriert ist und die optimistische Sperrstrategie verwendet wird, wird das vollständige Tupel implizit über den Status des Tupels versionsgesteuert, was sehr viel kostenintensiver ist.
@Entity
public class Employee
{
private long sequence;
// Für die optimistische Versionssteuerung verwendete Folgenummer.
@Version
public long getSequenceNumber() {
return sequence;
}
public void setSequenceNumber(long newSequenceNumber) {
this.sequence = newSequenceNumber;
}
// Weitere get/set-Methoden für andere Felder des Employee-Objekts.
}
Ein OptimisticCallback-Plug-in muss die Schnittstelle "OptimisticCallback" implementieren und die folgenden Konventionen für ObjectGrid-Plug-ins einhalten. Weitere Informationen finden Sie inSchnittstelle "OptimisticCallback".
Die folgende Liste enthält Beschreibungen und Hinweise für alle Methoden in der Schnittstelle "OptimisticCallback":
Dieser Sonderwert wird von der Methode "getVersionedObjectForValue" zurückgegeben, wenn die OptimisticCallback-Implementierung keine Versionsprüfung erfordert. Die integrierte Plug-in-Implementierung der Klasse "com.ibm.websphere.objectgrid.plugins.builtins.NoVersioningOptimisticCallback" verwendet diesen Wert, weil die Versionssteuerung inaktiviert ist, wenn Sie diese Plug-in-Implementierung angeben.
Die Methode "getVersionedObjectForValue" kann eine Kopie des Werts oder ein Attribut des Werts zurückgeben, das für Versionssteuerungszwecke verwendet werden kann. Diese Methode wird aufgerufen, wenn ein Objekt einer Transaktion zugeordnet wird. Wenn in eine BackingMap kein Loader integriert ist, verwendet die BackingMap diesen Wert während der Festschreibung, um einen optimistischen Versionsvergleich durchzuführen. Der optimistische Versionsvergleich wird von der BackingMap verwendet, um sicherzustellen, dass die Version des Map-Eintrags seit dem ersten Zugriff der Transaktion, die den Map-Eintrag geändert hat, nicht geändert wurde. Wenn eine andere Transaktion die Version für diesen Map-Eintrag bereits geändert hat, schlägt der Versionsvergleich fehl, und die BackingMap zeigt eine Ausnahme des Typs "OptimisticCollisionException" an, um eine Rollback-Operation für die Transaktion zu erzwingen. Wenn ein Loader integriert ist, verwendet die BackingMap die Informationen für die optimistische Versionssteuerung nicht. Stattdessen ist der Loader für die Durchführung der optimistischen Versionssteuerung und die Aktualisierung der Versionssteuerungsinformationen zuständig, sofern dies erforderlich ist. Der Loader ruft gewöhnlich das erste Versionssteuerungsobjekt von dem LogElement-Objekt ab, das an die Methode "batchUpdate" im Loader übergeben wurde, die aufgerufen wird, wenn eine Flush-Operation durchgeführt oder eine Transaktion festgeschrieben wird.
public Object getVersionedObjectForValue(Object value)
{
if (value == null)
{
return null;
}
else
{
Employee emp = (Employee) value;
return new Long( emp.getSequenceNumber() );
}
}
Wie im vorherigen Beispiel gezeigt, wird das Attribut "sequenceNumber" in einem vom Loader erwarteten Objekt des Typs "java.lang.Long" zurückgegeben. Dies impliziert, dass die Person, die den Loader geschrieben hat, auch die EmployeeOptimisticCallbackImpl-Implementierung geschrieben hat bzw. eng mit der Person zusammengearbeitet hat, die EmployeeOptimisticCallbackImpl implementiert hat, z. B. mit dieser Person den von der Methode "getVersionedObjectForValue" zurückgegebenen Wert vereinbart hat. Das OptimisticCallback-Standard-Plug-in gibt den Sonderwert NULL_OPTIMISTIC_VERSION als Versionsobjekt zurück.
public void updateVersionedObjectForValue(Object value)
{
if ( value != null )
{
Employee emp = (Employee) value;
long next = emp.getSequenceNumber() + 1;
emp.updateSequenceNumber( next );
}
}
Wie im vorherigen Beispiel gezeigt, wird das Attribut "sequenceNumber" um eins erhöht, so dass beim nächsten Aufruf der Methode "getVersionedObjectForValue" der zurückgegebene Wert vom Typ "java.lang.Long" einen langen Wert hat, der dem ursprünglichen Folgenummernwert plus eins entspricht, z. B. dem nächsten Versionswert für diese Employee-Instanz. Dieses Beispiel impliziert, dass die Person, die den Loader geschrieben hat, auch die EmployeeOptimisticCallbackImpl-Implementierung geschrieben hat bzw. eng mit der Person zusammengearbeitet hat, die EmployeeOptimisticCallbackImpl implementiert hat.
Diese Methode schreibt den versionsgesteuerten Wert in den angegebenen Datenstrom. Je nach Implementierung kann der versionsgesteuerte Wert verwendet werden, um optimistische Aktualisierungskollisionen zu identifizieren. In einigen Implementierungen ist der versionsgesteuerte Wert eine Kopie des ursprünglichen Werts. Andere Implementierungen können eine Folgenummer oder ein anderes Objekt haben, um die Version des Werts anzugeben. Da die tatsächliche Implementierung nicht bekannt ist, wird diese Methode bereitgestellt, damit die richtige Serialisierung durchgeführt werden kann. Die Standardimplementierung ruft die Methode "writeObject" auf.
Diese Methode akzeptiert die serialisierte Version des versionsgesteuerten Werts und gibt das tatsächliche versionsgesteuerte Wertobjekt zurück. Je nach Implementierung kann der versionsgesteuerte Wert verwendet werden, um optimistische Aktualisierungskollisionen zu identifizieren. In einigen Implementierungen ist der versionsgesteuerte Wert eine Kopie des ursprünglichen Werts. Andere Implementierungen können eine Folgenummer oder ein anderes Objekt haben, um die Version des Werts anzugeben. Da die tatsächliche Implementierung nicht bekannt ist, wird diese Methode bereitgestellt, damit die richtige Entserialisierung durchgeführt werden kann. Die Standardimplementierung ruft die Methode "readObject" auf.
Sie können zum Hinzufügen eines anwendungsdefinierten OptimisticCallback-Objekts zur BackingMap-Konfiguration zwischen zwei Ansätzen wählen: der XML-Konfiguration und der programmgesteuerten Konfiguration.
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>