Wenn eine Anwendung während einer Transaktion Änderungen an einer Map-Instanz vornimmt, werden diese Änderungen in einem LogSequence-Objekt verfolgt. Wenn die Anwendung einen Eintrag in der Map ändert, stellt ein entsprechendes LogElement-Objekt die Details der Änderung.
Die Loader (Ladeprogramme) erhalten ein LogSequence-Objekt für eine bestimmte Map, wenn eine Anwendung eine Flush- oder COMMIT-Methode für die Transaktion aufruft. Der Loader iteriert durch die LogElement-Objekte im LogSequence-Objekt und wendet jedes LogElement-Objekt auf das Back-End an.
ObjectGridEventListener-Listener, die bei einem ObjectGrid registriert sind, verwenden ebenfalls LogSequence-Objekte. Diese Listener erhalten für jede Map in einer festgeschriebenen Transaktion ein LogSequence-Objekt. Anwendungen können diese Listener wie Auslöser in einer konventionellen Datenbank verwenden, um festzustellen, ob sich bestimmte Einträge ändern.
Die folgenden protokollbezogenen Schnittstellen oder Klassen werden vom eXtreme-Scale-Framework bereitgestellt:
Ein LogElement-Objekt stellt eine Operation dar, die während einer Transaktion für einen Eintrag ausgeführt wird. Ein LogElement-Objekt besitzt mehrere Methode für den Abruf seiner verschiedenen Attribute. Die am häufigsten verwendeten Attribute sind der Typ und der aktuelle Wert, die mit den Methoden "getType()" und "getCurrentValue()" abgerufen werden.
Der Typ wird durch eine der in der Schnittstelle "LogElement" definierten Konstanten dargestellt: INSERT, UPDATE, DELETE, EVICT, FETCH oder TOUCH.
Der aktuelle Wert stellt den neuen Wert für die Operation dar, wenn diese eine Operation vom Typ INSERT, UPDATE oder FETCH ist. Wenn es sich bei der Operation um eine des Typs TOUCH, DELETE oder EVICT handelt, ist der aktuelle Wert null. Dieser Wert kann in ValueProxyInfo umgesetzt werden, wenn ein ValueInterface verwendet wird.
Weitere Einzelheiten zur Schnittstelle "LogElement" finden Sie in der API-Dokumentation.
In den meisten Transaktionen werden Operationen für mehrere Einträge in einer Map ausgeführt, so dass mehrere LogElement-Objekte erstellt werden. Sie müssen ein Objekt erstellen, das sich wie ein Verbund mehrerer LogElement-Objekte verhält. Die Schnittstelle "LogSequence" dient diesem Zweck und enthält eine Liste von LogElement-Objekten.
Weitere Einzelheiten zur Schnittstelle "LogSequence" finden Sie in der API-Dokumentation.
LogElement und LogSequence werden in eXtreme Scale und von ObjectGrid-Plug-ins, die von Benutzern geschrieben werden, häufig verwendet, wenn Operationen von einer Komponente oder einem Server an eine andere Komponente bzw. einen anderen Server weitergegeben werden. Beispielsweise kann ein LogSequence-Objekt von der ObjectGrid-Funktion für verteilte Transaktionsweitergabe verwendet werden, um die Änderungen an andere Server weiterzugeben, oder vom Loader auf den persistenten Speicher angewendet werden. LogSequence-Objekte werden hauptsächlich von den folgenden Schnittstellen verwendet:
In diesem Abschnitt wird veranschaulicht, wie die LogSequence- und LogElement-Objekt in einem Loader verwendet werden. Ein Loader wird verwendet, um Daten aus einem und in einen persistenten Speicher zu laden. Die Methode "batchUpdate" der Schnittstelle "Loader" verwendet ein LogSequence-Objekt:
void batchUpdate(TxID txid, LogSequence sequence) throws
LoaderException, OptimisticCollisionException;
Die Methode "batchUpdate" wird aufgerufen, wenn ein ObjectGrid alle aktuellen Änderungen auf den Loader anwenden muss. Der Loader erhält, gekapselt in einem LogSequence-Objekt, eine Liste der LogElement-Objekte für die Map. Die Implementierung der Methode "batchUpdate" muss durch die Änderungen iterieren und sie auf das Back-End anwenden. Das folgende Code-Snippet veranschaulicht, wie ein Loader ein LogSequence-Objekt verwendet. Das Snippet iteriert durch den Änderungssatz und erstellt drei JDBC-Stapelanweisungen: inserts, updates und deletes:
public void batchUpdate(TxID tx, LogSequence sequence) throws LoaderException {
// Zu verwendende SQL-Verbindung abrufen.
Connection conn = getConnection(tx);
try
{
// Liste der Änderungen verarbeiten und eine Gruppe vorbereiteter
// Anweisungen für die Ausführung in einer SQL-Operation update, insert oder delete
// im Stapelbetrieb erstellen. Die Anweisungen werden im stmtCache zwischengespeichert.
Iterator iter = sequence.getPendingChanges();
while ( iter.hasNext() )
{
LogElement logElement = (LogElement)iter.next();
Object key = logElement.getCacheEntry().getKey();
Object value = logElement.getCurrentValue();
switch ( logElement.getType().getCode() )
{
case LogElement.CODE_INSERT:
buildBatchSQLInsert( key, value, conn );
break;
case LogElement.CODE_UPDATE:
buildBatchSQLUpdate( key, value, conn );
break;
case LogElement.CODE_DELETE:
buildBatchSQLDelete( key, conn );
break;
}
}
// Die Stapelanweisungen ausführen, die mit der vorherigen Schleife erstellt wurden.
Collection statements = getPreparedStatementCollection( tx, conn );
iter = statements.iterator();
while ( iter.hasNext() )
{
PreparedStatement pstmt = (PreparedStatement) iter.next();
pstmt.executeBatch();
}
} catch (SQLException e)
{
LoaderException ex = new LoaderException(e);
throw ex;
}
}
Das vorherige Beispiel veranschaulicht die übergeordnete Verarbeitungslogik für das Argument "LogSequence". Das Beispiel zeigt jedoch nicht die Details der Erstellung einer SQL-Anweisung "insert", "update" oder "delete". Die Methode "getPendingChanges" wird für das Argument "LogSequence" aufgerufen, um einen Iterator für die LogElement-Objekte abzurufen, die ein Loader verarbeiten muss, und die Methode "LogElement.getType().getCode()" wird verwendet, um festzustellen, ob ein LogElement für eine SQL-Operation "insert", "update" oder "delete" bestimmt ist.
Sie können LogSequence- und LogElement-Objekte auch mit einem Evictor (Bereinigungsprogramm) verwenden. Ein Evictor wird verwendet, um Map-Einträge auf der Basis bestimmter Kriterien aus der BackingMap zu löschen. Die Methode "apply" der Schnittstelle "Evictor" verwendet LogSequence.
/**
* Diese Methode wird während der Cachefestschreibung verwendet, damit das
* Bereinigungsprogramm (Evictor) die Verwendung des Objekts in einer BackingMap-Instanz
* verfolgen kann. Diese Methode meldet außerdem alle Einträge, die gelöscht
* bereinigt.
*
* @param sequence LogSequence der Map-Änderungen
*/
void apply(LogSequence sequence);
Informationen zur Verwendung von LogSequence in der Methode "apply" finden Sie im Codebeispiel im Abschnitt Angepassten Evictor schreiben.
Manchmal müssen die LogElement-Objekte gefiltert werden, damit nur LogElement-Objekte mit bestimmten Kriterien akzeptiert und andere Objekte zurückgewiesen werden. Sie können beispielsweise ein bestimmtes LogElement auf der Basis eines bestimmten Kriteriums serialisieren.
LogSequenceFilter löst dieses Problem mit der folgenden Methode.
public boolean accept (LogElement logElement);
Diese Methode gibt "true" zurück, wenn das angegebene LogElement-Objekt in der Operation verwendet werden soll. Andernfalls gibt die Methode den Wert "false" zurück.
LogSequenceTransformer ist eine Klasse, die die Funktion "LogSequenceFilter" verwendet. function. Diese Klasse verwendet LogSequenceFilter, um LogElement-Objekte zu filtern und die akzeptierten LogElement-Objekte anschließend zu serialisieren. Diese Klasse hat zwei Methoden. Die erste Methode sehen Sie im Folgenden.
public static void serialize(Collection logSequences, ObjectOutputStream stream,
LogSequenceFilter filter, DistributionMode mode) throws IOException
Diese Methode erlaubt dem Aufrufenden, einen Filter zu definieren, um die LogElement-Objekte zu ermitteln, die in den Serialisierungsprozess aufgenommen werden. Der Parameter "DistributionMode" ermöglicht dem Aufrufenden, den Serialisierungsprozess zu steuern. Der Wert muss nicht serialisiert werden, wenn der Verteilungsmodus auf Invalidierung eingestellt ist. Die zweite Methode dieser Klasse ist die Methode "inflate", die im Folgenden gezeigt wird:
public static Collection inflate(ObjectInputStream stream, ObjectGrid
objectGrid) throws IOException, ClassNotFoundException
Die Methode "inflate" liest die serialisierte Form der Protokollfolge, die mit der Methode "serialize" aus dem bereitgestellten Objekteingabedatenstrom erstellt wurde.