-
Notifications
You must be signed in to change notification settings - Fork 63
Description
The current implementation of this behavior only provides concurrency in a single Yii Application instance scenario. The static variable $_cached tracks all of the instances of Nested Set AR's in a single Yii Application instance and keeps left, right, level, and root attributes current.
The problem with this assumption is that each request served by a web server generates a new instance of a Yii Application. Furthermore, load balanced applications can create even more instances of Yii Applications on different servers. The static $_cache variable does not track anything outside the current Yii Application instance, meaning that the possibility for a stale cache exists both on a single and multi server implementation.
Databases transactions can solve this problem. This behavior does use transactions, but it uses potentially stale data that was fetched before the transaction was started. The following methods use potentially stale data:
-save(): This will by default save left, right, root, and level attributes. These could have been changed on another instance since the model was loaded. These attributes should not be saved by default.
-delete(): This uses $owner attributes, which were loaded before the DB Transaction was started. These attributes should be refreshed once the DB Transaction starts.
-addNode(): This uses $key (computed based off $target) and $target attributes, which were loaded before the DB Transaction was started. $target should be refreshed once the DB Transaction starts and $key should be computed after $target has been refreshed.
-moveNode(): same problem as addNode() except $owner attributes are also used.
-moveAsRoot(): same problem as delete().
Please let me know if you think refreshing this data inside of the Database transaction would fix the Concurrency issues that presently exist. I'm happy to contribute a fix.