This discussion includes the questions asked from the recent CLSA Community webinar on Savable Data Pages ... and their answers from our presenters!
Savable Data Page fundamentals
What is the order of execution in a Flow Action that references Savable Data Pages?
Savable Data Pages
Post-processing Data Transform
This allows the Post-Processing Activity to post-process or handle errors raised by the Savable Data Pages.
When the Savable Data Page save plan gets triggered, do the data sources get executed first?
In order to have content on the data page to save, the data page will have been referenced earlier. The earlier reference to load the data page will load from the data sources; the save action performs only the save plan.
Is that a call to an endpoint's GET API prior required before calling the corresponding POST API in a save plan?
Not necessarily. The Savable Data Page can be loaded from any source (REST, Database, Data Transform) before the save plan calls the relevant POST API.
What is the best way to configure Saveable Data Page that creates a new record when it receives a new key, but updates when it receives an existing key?
You can configure multiple data sources and save plans which execute based on when conditions that check whether the key is present or not.
For REST connectors, the fetch *-Int-* class and save *-Int-* class can be different right? How can you transform from one class to the other?
While fetching, you use a response data transform on the data source configuration to transform that *-Int-* instance to the *-Data-* instance of the data page.
Then when saving, you use the request data transform in the save plan to transform the *-Data-* instance to the *-Int-* instance for the save endpoint.
Note that REST connectors can now use JSON Data Transforms to map directly between JSON to the *-Data-* instance (and back) which avoids the need for *-Int-* classes that reflect the data model of the JSON messages.
Can we author Savable Data Pages from app studio?
Yes, Savable Data Pages are created automatically when the source system is Pega.
For externally sourced data pages, you can configure save plan using 'Configure Save' option in App Studio.
Is there a function to trigger save action that can be used in data transforms?
No. There is no way to trigger save actions from a data transform.
Use data transform rules for setting values on a clipboard page, or mapping values between clipboard pages. Flow actions are the best rule type to orchestrate saving data as they provide transaction management for updates to the Pega database, and can orchestrate error handling of updates made in other systems of record.
When the source is Lookup and the system doesn't find any record, how is that (data not found) handled?
You can check for the record existence after attempting the lookup in the response data transform. If the lookup did not find a record, the response data transform can clear the errors and populate default details on the data page to allow creation of a new record via the save plan.
For multiple save plans, can you stop the execution of the second save plan when the first one fails?
If a save plan on a Savable Data Page fails, any further save plans on that Savable Data Page are not attempted.
Is there a workaround to continue with further save plans even when the first save plan fails by clearing the messages or error page in post processing of first save plan?
This is a good question. So long as the messages from first save plan are cleared before that save plan completes (that is, using the response data transform), Pega Platform will deem the save plan to have been successful and proceed to the next save plan.
Use with caution, as masking the incidence of errors also makes it harder for rules outside of the Savable Data Page - for example, the Flow Action's post-processing activity - to determine whether errors occurred and compensating actions need to be performed. Such an approach risks introducing data integrity issues across the systems of record used by this Savable Data Page.
Consider whether it is better for that first save plan to use an activity to attempt saving to the first system of record, and invoke a secondary save plan in the case of error.
Handling multiple records
How can we iterate over a page list of records and insert/update those using Savable Data Page?
Save operations are performed one instance at a time. As of 8.6, when looking to save each page list item to the Pega database, this is best implemented as an Activity that loops over the page list and issues an Obj-Save for each items needing to be created or updated.
Depending on the APIs available for systems of record accessible via REST, it may be possible to send a invoke a single REST Connector to save multiple list items.
Can we insert/update multiple records at a time?
Further to the previous scenario:
Multiple save plans on a single Savable Data Page can run, typically for when a single save action needs to be recorded in multiple systems of record
Multiple Savable Data Pages can run in a Flow Action, typically for when multiple data items have been updated in an assignment and all need to be persisted on its completion.
Can Savable Data Pages be used for cascaded updates on embedded pages?
For example, updates on Person as well as Address where Address is an embedded page.
When you trigger a database save option, it will try to save the current page. Embedded properties will be saved if it is a case type and has BLOB column.
If Address is stored as a separate data item - in Pega or in another system of record - you will have to call the save plan for Address seperately.
Remember though that multiple save plans on a Savable Data Page can run, so the saving of a Person's Address data could be implemented as an additional save plan on the Savable Data Page for Person.
Multiple Systems of Record (SORs)
How does it work if I have to save to multiple external systems using same Savable Data Page?
You can configure multiple save plans executed based on whether the When conditions for each save plan evaluates to true.
All save plans whose When conditions evaluate to true are run, which allows multiple SORs to be invoked as part of saving the one data page.
When the record does not exist in the database and will be created the first time, no record can be retrieved that will be updated. What Savable Data Page configuration is needed to handle this?
Have a condition - either in the When rules for selecting a data source; or in the response data transform of the lookup - for checking if the record exists or not. Often in such a scenario, the caller (that is, the case) does not yet have the identifier of the record, so a Data source When rule testing whether the data page's key parameter is blank may be sufficient.
Once you have determined that there is no record available to retrieve, use a data transform to populate the default values for a new instance, if the expectation is that the case will capture details for the creation of a new record.
Can we call Savable Data Pages from an asynchronous activity or declare trigger?
Yes, the Savable Data Page is just like any other rule.
As with any asynchronous execution, make sure that your data source and save options do not assume any context is available on the clipboard.
Can we use Savable Data Pages from a Job Scheduler where we need to manually commit?
Save plans that use the Database save save type issue a deferred save, and are committed on successful Flow Action completion or when the Commit method is used (if needed by a Job Scheduler). Consider their behavior the same as how you would use Obj-Save in a Job Scheduler activity.
Note that Commit has no bearing on save plans that use other save types. For example, whether an external system of record commits updates transmitted via a REST Connector is entirely up to that REST API.
Can we use Savable Data Pages to delete data from the Pega database?
Delete is not currently supported as a save type. Use an Activity to orchestrate database deletions if that is an aspect of your Savable Data Page.
So, if I want to use a Savable Data Page for an Address in a Work-UpdateAddress case, but a read only data page elsewhere in the system (to utilise caching options), do I need to specialize the .Address property in the Work-UpdateAddress case type?
The Update Address case type has the behavior specific to capturing changes to Address data. Consider naming the property on the Work-UpdateAddress case type something like .AddressEditable. This keeps the data presented and captured for update distinct from the readonly scenarios used more commonly across the application under .Address.
Will Savable Data Pages work in mobile apps? Especially screens in offline mobile app case types?
Auto-populate properties using the "Copy from data page" option enable the relevant snapshot of the Savable Data Page data to be stored as part of the case data. This makes Savable Data Page data equally as available as other case data when working offline.
How to handle the create scenario with respect to multiple concurrent threads (for example, creating multiple new instances)
Each REST POST/PUT request from Pega to another SOR is a distinct transaction. The target system should do transaction management such that isolation is maintained in their SOR while doing create or update.
For database save plans performed across multiple threads, the behavior is the same as if Obj-Save had been invoked across multiple threads. That is, by default they are deferred saves within the context of the current Requestor that owns the threads. The next Commit - ideally triggered by the Pega Engine at a a flow processing commit point - sends them to the database.
How can Savable Data Pages handle concurrency to the database table where row-level locking is needed? In an activity, Obj-OpenByHandle with lock helps with handling concurrency
Can the same data entity by manipulated by multiple cases? Is there locking available?
Internally the pxUpdateRecord API is used for Database save actions.
If the data type to be saved requires locking, the lock is sought at the time of the save.
Will the lock will be lost on the case after save of a Savable Data Page? Will there be any difference with optimistic locking or default locking?
Internally the pxUpdateRecord API is used for Database save actions.
The save for a Savable Data Page is typically performed on a data item and not on an entire case. Pega Platform continues to manage case locking the same as before.
Let Pega continue to open work items, acquire their locks, save them and release their locks independent of Savable Data Pages. Use Savable Data Pages for data instances.
How to rollback a Savable Data Page in the case of a save failure in a remote SOR?
As of Pega Platform 8.6, rollback (compensation) logic is not encapsulated in the Savable Data Page. The context that calls for a save to be performed on a Savable Data Page needs to check for errors incurred with remote SORs and implement rollback (compensation) logic. When Savable Data Pages are referenced in a Flow Action, the best place to implement this is in the Flow Action's post-processing activity.
How does the out-of-the-box commit work with Savable Data Pages when used in Agent processing? One of the problems we observed was auto-commit did not happen in this scenario, and led us to use explict save again!
Savable Data Pages with database save actions issue deferred saves by default. In an activity such as an Agent, Job Scheduler or Queue Processor, anywhere an explicit commit was needed for Obj-Save will continue to be needed when using Save-DataPage.
Similar to Obj-Save, the Save-DataPage step method has a WriteNow parameter which can be used in those rare circumstances where an instant commit is needed. The intended usage - like Obj-Save - is that Save-DataPage issues a deferred save which is committed by the next commit point that the Pega Engine reaches.
Earlier with Obj-Save we can queue multiple deferred saves of multiple class instances and can control batch commit to make sure all Obj-Saves are successful.
If multiple Savable Data Pages are present, how we can achieve the same result?
Use a Savable Data Page for each class of data that needs saving.
If known at design time what will need saving, reference the relevant Savable Data Page for each instance to save in the Flow Action of the action that requires those changes to be recorded. If any of the referenced Savable Data Pages fail, the Pega Engine rolls back all deferred saves from earlier Savable Data Pages in the Flow Action.
If the Savable Data Pages use save options that are not Database save, the post-processing activity for the flow action runs after the Savable Data Pages. In here, each Savable Data Page in the Flow Action can be checked using the hasMessages when rule to determine those that are in an erroneous state. At this point, the activity can implement handling for any earlier Savable Data Pages that issued successful REST operations, which are outside of Pega's transaction management scope, and need to be undone.
If there are three save plans in a Savable Data Page, if the first and second save are successful - but the third one fails - is there a way to roll back the first two?
In each response data transform, you can update a property on the data page to indicate which save plan was last executed successfully. When the Savable Data Page is referenced from a Flow Action, control will eventually pass to the Flow Action's post-processing activity, which can inspect that property on the data page to determine the successful/failed save actions and determine the rollback (compensation) behavior that needs to be performed.