public interface TransactionChaining
queues
 of
 DSRequests to be "chained" together, such that later
 DSRequests in
  the queue can use the results of previous requests in the queue.  This allows you to
  declaratively handle various situations where information only becomes available during the
  processing of a queue.
  
  To see an example of server-driven transaction chaining used to commit a mixed transaction of 
  an Order and related OrderItems, see the 
 Master/Detail Add sample.
  
Transaction Chaining is only available with Power Edition licenses or better. See the Editions & Pricing page for details.
  As an example of Transaction Chaining, consider an application that needs to do a
  master-detail add, which involves saving a new Record representing a sales order to an
  order DataSource, and also saving several related Records representing
  individual items in the order to an orderItem DataSource.  The Records for the
  individual orderItems need to set up foreign keys referencing the primary key
  assigned to the Record for the order, but the primary key of the
  order record is assigned only when the Record is inserted into the database; it
  cannot be known up-front.
  
  You could resolve this programmatically - for example, you could use DMIs to store and
  retrieve the PK value using servletRequest attributes - but Transaction Chaining
  gives you an elegant, declarative, code-free alternative, giving you a way to declare that the
  foreignKey value for the orderItem records should use the primary key value
  resulting from the creation of the order record earlier in the same queue.
  
As another example, consider an application that allows a user to submit a free-form question which must be persisted to the database like a normal update, but which should initially show the user a list of previously-provided answers that appear to be relevant. The operation that handles the add of the question categorizes it by analyzing the text, and the category is added to the record inserted into the database, and thus to the record returned in the response. Now, via transaction chaining, a "fetch" operation later in the queue can pick up the newly assigned category and use it in criteria to fetch the list of related answers.
 Transaction Chaining is implemented by specifying DSRequestModifiers in 
 OperationBinding.values and
 OperationBinding.criteria. 
 These two properties
  provide a general means of declaratively modifying DSRequests server-side, and transaction
  chaining is only one of their uses.  They can also be used, for example, to implement security
  rules, by adding the currently-authorized user to the criteria of all fetch requests.
  
  Specifically for transaction chaining, you specify criteria and/or 
  values entries on the operationBinding where the 
 value property references the
 $responseData
  Velocity context variable - see the "value" link for more details.  
  Alternatively, you can use the RPCManager APIs getFirstResponse()
   and getLastResponse() to get access to the same information, either 
  programmatically from DMI or custom DataSource Java code, or in 
 JSR 223 scripts, or in Velocity expressions via
 the $rpc 
  context variable.
  
fieldValueExpressions.  The
 primary intended use 
  case is a master-detail add, where the detail records require the master's primary key for
  use as foreign keys, but that value is not known until the master record has been inserted.
 In such a case, you create a queue of
 requests, with the 
  add of the master record first, followed by the detail records, each of which has
  fieldValueExpressions set up to use $masterId like so:
  
  
      DSRequest properties = new DSRequest();
      Map fve = new HashMap();
      fve.put("fkField", "$masterId");
      properties.setFieldValueExpressions(fve);
      myDataSource.addData(record, callback, properties);
  
  It is also possible to achieve the same thing in a less compact but more flexible way by
  using the $responseData context variable (note that client-driven usages of 
  $responseData are limited for security reasons - see 
 fieldValueExpressions for
 details).  This approach
  allows you to reference values where there is no declared foreignKey relationship, and it 
  allows you to reference responses other than the most recent one.  For example:
  
  
      DSRequest properties = new DSRequest();
      Map fve = new HashMap();
      fve.put("anyField", "$responseData.first.anyOtherField");
      properties.setFieldValueExpressions(fve);
      myDataSource.addData(record, callback, properties);
  
  To see an example of client-driven transaction chaining used to commit a mixed transaction 
  of an Order and related OrderItems, see the 
 Master/Detail Add sample.
  
 As with Server-Side Transaction Chaining, fieldValueExpressions can be used to
 affect 
 dsRequest.criteria as well. For example, perhaps you are fetching the most recent
 Order 
 and its related OrderItems, by sorting the returned Orders by orderDate and asking
 for 
 only one record. Since you are fetching the most recent Order, you don't have the Order.orderId
 value 
 available to fetch related OrderItems by passing the Order.orderId value as
 criteria for 
 OrderItem.orderId. You need the primaryKey of whichever Order turns
 out 
  to be most recent. Use fieldValueExpressions like so to solve this case:
  
  
  
       RPCManager.startQueue();
       DSRequest orderRequestProperties = new DSRequest(DSOperationType.FETCH);
       orderRequestProperties.setStartRow(0);
       orderRequestProperties.setEndRow(1);
       orderRequestProperties.setSortBy(new SortSpecifier("orderDate", SortDirection.DESCENDING));
  
       DataSource.get("Order").fetchData(null, null, orderRequestProperties);
  
       DSRequest orderItemRequestProperties = new DSRequest(DSOperationType.FETCH);
       orderItemRequestProperties.setFieldValueExpressions(new HashMap() {{
           put("orderId", "$responseData.first.orderId");
       }});
   
       DataSource.get("OrderItem").fetchData(null, null, orderItemRequestProperties);
 
       RPCManager.sendQueue();
   
  
  
Standalone DataSource Usage for
 examples on how to
  do this.