Details
-
New Feature
-
Resolution: Fixed
-
None
-
None
-
None
-
Empty show more show less
Description
The automatic versioning of entities should ensure, that users get a feedback in the frontend if they tried to overwrite an entity which was changed in the meantime on the server by another user.
Usage of the Versioning in an entity directly:
- create a DB field entityVersion (and in corresponding JS model):
ALTER TABLE `XXXX` ADD COLUMN `entityVersion` int(11) NOT NULL DEFAULT 0 AFTER `id`;
- create a trigger in the DB therefore, the trigger raises an DB error is the version does not match:
- for mysql version < 5.5, error is raised by unimplemented method CALL
DELIMITER | CREATE TRIGGER LEK_task_versioning BEFORE UPDATE ON LEK_task FOR EACH ROW IF OLD.entityVersion + 1 != NEW.entityVersion THEN CALL raise_version_conflict; END IF| DELIMITER ;
- for mysql >= 5.5, error is raised by SIGNAL → UNTESTED and UNIMPLEMENTED in PHP try catch!
CREATE TRIGGER LEK_task_versioning BEFORE UPDATE ON LEK_task FOR EACH ROW IF OLD.entityVersion + 1 != NEW.entityVersion THEN SIGNAL SQLSTATE '45000' SET MESSAGE TEXT = 'VERSION CONFLICT' END IF;
- for mysql version < 5.5, error is raised by unimplemented method CALL
- versioning is only triggered, if on saving the entity from the GUI, the old version is also delivered to be saved
That means, that the entityVersion field in the JS model has always to be set to dirty!
Usage of versioning in some kind of "sub" or "assoc" entity (like the taskUserAssoc for tasks).
Some times we dont want to version a single entity itself, but a whole set of entities belonging to another entity.
For this case we can use "external versioning":
- if an entity should use external versioning, make the entity class using the trait: "ZfExtended_Models_Entity_TExternalVersion"
- the version itself must now be delivered by HTTP headers, which are handled automatically on the PHP side by the RestController if using the above trait in the entity.
- The validation process in the DB must also be triggered manually (e.g. by loading, setting and saving the master/parent entity) or by using TExternalVersion::increaseParent()
- In the GUI the reading, saving and updating the new version in the parent entity must be implemented as needed
todo:
- Vorbedingung: Die Versionierung dient nur dazu nicht mehr aktuelle Daten im Client zu identifizieren und diesem einen entsprechenden Hinweis zu senden. Somit muss es möglich sein Daten zu aktualisieren, ohne die Versionierung zu ändern wenn dies für das Frontend nicht nötig ist (z.B. Locking Informationen).
- Es muss vom Client immer eine Referenzversion mitgeschickt werden gegen die verglichen wird, bei Main Entities ist dies kein Problem, das JS Model stellt sicher, dass die vorhandene entityVersion wieder zum server geschickt wird. Bei subentities siehts ähnlich aus, es muss im JSModel ebenfalls ein entitiVersion Feld angelegt werden, allerdings muss dies durch den Programmierer mit der version des parent entitiy manuell befüllt werden. Ebenfalls muss der Programmierer sicherstellen das parent entity zu aktualisieren!
- von mysql: Hinweis: Zurzeit werden Trigger nicht von kaskadierenden Fremdschlüsselaktionen aktiviert. Dieser Mangel wird jedoch so bald wie möglich behoben.
- DELETE trigger möglich, aber nur wenn versionswert per SET zum abgleich übergeben worden ist!
- auch kann bei DELETE kein Ref Wert mit übergeben werden, das heißt das muss per Header erfolgen!
- Versionierung kann leider einfach übergangen werden, in dem keine Referenzversion mitgegeben wird bei Haupt Entities
- Bei subentites muss die version explizit auf null gesetzt werden um an der Versionierung vorbei zu arbeiten (zumindest bei UPDATE)
- Entites: CRUD → C: v=0 per DB default, R: v wird ausgespielt, U: v++ per trigger; D: v unerheblich da nicht mitgegeben
- SubEntites: CRUD → C: v=vMainAlt, per Trigger, R: lokale v (vMainAlt) wird ausgespielt, U: vMain++ v = vMainAlt; D: Referenz v per HEADER zum Abgleich
- Der Client ist dafür verantwortlich, an die aktuellste Version zu kommen (sprich in der PUT Antwort eines Subentities wird keine Versionsnummer des Parents zurückübermittelt)
- den controller des zu versionierenden entities auf abgeleitete put/post/delete actions überprüfen, dass hier $this->processClientReferenceVersion(); mit drin ist
- JS: task::set override to ensure that entityVersion is always send in a general manner? actually only in task model
This task is implicitly done in TRANSLATE-113 and is listed as own task for documentation only.
Attachments
Issue Links
- blocks
-
TRANSLATE-113 Task Management Window
- Done