Initiating an Interaction Cycle
When a component acts directly on its representations or representation objects, this component must call the appropriate feedback functions declared on the classes IlsRpObject and IlsRepresentation so that the server is notified of the modifications. By default, each time one of these functions is called, a component-to-server transaction is implicitly created and committed, which results in the execution of a complete interaction cycle.
For instance, let us assume that a table representation is associated with a DepartementTable view and that a row object of type RowR belongs to this representation. The following code notifies the server of the following events, in this order:
The first cell of
row has been modified.
The second cell of
row has been modified.
row->onUpdate(row->getAttributeId("column",1),"J.K Robinson");
row->onUpdate(row->getAttributeId("column",2),10000);
At runtime, these events create and commit two component-to-server transactions, implying two interaction cycles.
To optimize component/server interactions, you should buffer notification and send a single transaction when a logical set of updates is completed.
Buffering at Representation Object Level
The member functions IlsRpObject::beginC2SUpdate and IlsRpObject::endC2SUpdate control how notification to the server is buffered at each representation object level.
Now, let us modify the previous code so that only one interaction cycle is executed:
row.beginC2SUpdate();
row.onUpdate(row->getAttributeId("column",1),"J.K Robinson");
row.onUpdate(row->getAttributeId("column",2),10000);
row.endC2SUpdate();
The interaction cycle with the server will be initiated only when the last instruction row.endC2SUpdate is executed.
You may want to discard the update notification currently buffered about an object. In this case, just call the function IlsRpObject::discardC2SUpdate, like this:
row.beginC2SUpdate();
row.onUpdate(row->getAttributeId("column",1),"J.K Robinson");
row.onUpdate(row->getAttributeId("column",2),10000);
row.discardC2SUpdate();
Important: The execution of these intructions on the same object is not thread safe. Therefore, if a component needs to interact on the same representation object concurrently from different threads, that component is responsible for ensuring mutual exclusion. |
Buffering at Representation Level
Buffering notification of updates at representation level is the usual practice.
It allows you to initiate an interaction cycle only when the whole representation
has reached a consistent state. This is the purpose of the member functions IlsRepresentation::beginC2STransaction and IlsRepresentation::endC2STransaction. Note that both buffer levels—that is, at representation-object level and at representation level—can be used simultaneously, as shown in this code sample.
Example
IlsRepresentation* repres=row1.getRepresentation();
assert(repres && (repres==row2.getRepresentation());
repres->beginC2STransaction();
row1.beginC2SUpdate();
row1.onUpdate(r->getAttributeId("column",1),"J.K Robinson");
row2.beginC2SUpdate();
row2.onUpdate(r->getAttributeId("column",1),"L.M. Drummond");
row1.onUpdate(row2->getAttributeId("column",2),10000);
row1.endC2SUpdate();
row2.onUpdate(row2->getAttributeId("column",2),200);
row2.endC2SUpdate();
repres->commitC2STransaction();
In this example, only one transaction is sent to the server when the function IlsRepresentation::commitC2STransaction is called. This transaction notifies subscribers about the modifications of both row1 and row2. Declaring the functions IlsRpObject::beginC2SUpdate and IlsRpObject::endC2SUpdate on the representation objects is not mandatory in this example. However, this is recommended as an optimization technique that allows you to group all the modifications of the same object. Note that in this case, the modifications registered at object level are sent to the representation level only when the function endC2SUpdate is called.
The function IlsRepresentation::rollbackC2STransaction rolls back the modification currently registered at the representation level.
This rollback can be performed locally on the component, but you can also request the server to re-notify the current state of the modified objects so that the component is not constrained to implement its own rollback. This point will be discussed in
Default Component-to-Server Transaction Status. You can also refer to
“Transaction Control” in the
IlsMvComponent class description in the Rogue Wave Server
Reference Manual.
Important: As we mentioned about representation objects, the buffering of component-to-server transactions at representation level is not thread safe. Therefore, if a component needs to interact with the same representation concurrently from different threads, that component is responsible for ensuring mutual exclusion. |
Buffering at Component Level
Notification of changes can also be buffered at component level through the functions IlsMvComponent::beginC2STransaction, IlsMvComponent::commitC2STransaction, and IlsMvComponent::rollbackC2STransaction.
This mechanism allows the component to update a set of representations locally so as to initiate a single interaction cycle with the server.
Rogue Wave Server supports multithread component-to-server transactions. This means that you can begin, commit and rollback different transactions in different threads. To do this, just execute the function IlsMvComponent::setC2SMT after the component has been created.
Version 6.3
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.