Resoa Persistence - the Task object
Resoa Persistence internally uses Resoa Services for the Master/Slave management, declared within the resoa.persistence.xsd file.
The most important type for every persistent transaction is the Task.
The task object instance is created on the node, where the request initially arrived and processed due to the persistence policy rules. It contains a series of Instructions. A MASTER node first processes all declared locks, then checks for consistency restrictions and in case of no conflicts it finally performs the atomic executions to the physical storage.
Check the class PersistentTransaction, it offers functions for the automatic Task instance creation and execution. Within service programming you use the interface ResoaPersistence, implemented by Persistor.
Task objects are JSON serialized, encrypted and stored as a local Journal file. These Journals are deleted again, if the final processing to the persistent backend has succeeded.
Object relation types
Persistent relations are declared within the resoa.xml file of a persistent service domain. The following types are available:- CREATE_UPDATE: Create the linked object, if it not yet exists, or update the existing record
- CREATE: Create the linked object, if it not yet exists, do not update existing data.
- LINK_IFEXIST: Link to an existing object. If it does not exists in related database, do not replace the reference JSON by the ID.
- LINK_INSIST: The referenced object must exist, if not, an IntegrityException is thrown by the Persistor.
The MASTERCOMMIT Policy
Use this policy for transactions, which must be executed by MASTER before a COMMIT is indicated to the request.
The final slave storage transactions happen with delay. Requests of type CREATE_NEW and tasks with relations of type LINK_INSIST are always executed under this Policy.
- Write Logfile to local storage, broadcast Task to Resoa nodes, serving the same domain
- Wait for a MASTERCOMMIT of the MASTER node
- Process into local storage as well and commit transaction to requestor
- Write Task to physical storage without Journal, broadcast committed task to Resoa nodes, serving the same domain
- Do not wait for a COMMIT of SLAVE nodes
- If the request runs into timeout before the MASTER commit, the timeout is registered at the Controller persistor and a CANCEL send to all domain nodes
- The taskID of the CANCEL is cached within the execution threadpool, so the MASTER node might catch it before it starts with the task execution
- If the CANCEL takes place, the Controller persistor is informed and the pending timeout marked as cleared (does not appear in any error logs!)
- If the MASTER commits the task before it receives the cancel, the Controller persistor is informed about this delayed COMMIT. The task JSON is stored in a dedicated database
- Transaction timeout is a static parameter in Persistor class
The LOGILEPERSIST Policy
Use this policy when transaction speed is more important than grid synchronization speed. The request is committed, if- the task object could be generated without conflicts
- The task is serialized to JSON and stored as file within the local journal folder
- The task is broadcasted to all nodes within the grid, serving the domain.
- Write Logfile to local storage, broadcast Task to Resoa nodes, serving the same domain
- Indicate LOGFILE_PERSIST to requestor and finish the request
- ====== Asynchronous processing ========
- MASTER processes task into final storage, the SLAVES are informed and will process into storage as well. Strict transaction sequence is guaranteed by MASTER! LogFile is deleted after final storage execution
- SLAVES process tasks, received from MASTER with status COMMIT to local physical storage as well and delete the journal file
- Transactions, which could be not processed by MASTER for any reason, are broadcasted to the controller nodes, which archive these requests
- Create Journal file and write it to local folder. Broadcast the task to Resoa nodes, serving the same domain
- Indicate LOGFILEPERSIST to requestor and finish the request
- ====== Asynchronous processing ========
- Task is processed into underlying storage, handled by internal thread pool
- After having finished with final storage transaction, SLAVE node get a COMMIT notification, the Journal file is deleted
Object inheritance
Let's assume you assigned a class org.foo.Course as persistent within resoa.xml, but your xsd defines another type org.foo.MathCourse, extending Course. MathCourse will be persistent as well without any further declarations in resoa.xml, all inherited types of a persistence type are persistent as well. The entityname, used within the Instruction structure, assign the real type of the stored record, it will be attached to the JSON root by the key class as well. This is essentially for unmarshalling, otherwise the system would cast your MathCourse instance to the wrong type Course.