This seems to be a general concurrency handling pattern in Gemstone: Situation: I have an object, which holds a Set in one of its attributes (slots). Question: I want to remove this object, IF the set is empty. But what happens, if another task is just adding an item to this set ? How can Gemstone find a commit conflict ? I do not want to use locks on objects. Any other idea ? _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In order to better understand the situation, I have two questions:
(1) Why do you want to remove an empty Set from an object? (2) Why not use locks? James
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
I do not want to remove an empty set from an object, perhaps this makes it much clearer: Transaction A: +-------------------> check if set in object attribute slot is empty -> remove object -> ------------------------------------+ Transaction B: + -----------------> add element to set in object attribute slot -> ------------ + I would not assume, that this results into a commit conflict .... James Foster <[hidden email]> hat am 27. Februar 2019 um 15:59 geschrieben:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Hello Marten, a simple but effective strategy could be to include something
like theEmptySet add: #deleted in transaction A. This would
conflict with a potential addition made by transaction B. As far
as I understand your use case, the Set-Entry #deleted (or
whatever) won't be a problem if no conflict occures, since the
object with the Set will be GCed in that case. Br, Ralph
Am 27.02.2019 um 16:54 schrieb Marten
Feldtmann via Glass:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Ralph Mauersberger via Glass <[hidden email]> hat am 27. Februar 2019 um 18:04 geschrieben: Yes, that's a solution. a) You check if the set is empty b) then you remove the object, holding this empty set, from the persistence closure c) but you add any object to this empty set (like nil) But it will NOT work, if the set is an RcIdentitySet or stuff like this ... Marten
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by GLASS mailing list
Marten,
Perhaps I’m getting confused by the reference to "an empty set” and then the instructions to “remove object”. Are there two collections? One in the object and one holding the object? I believe you are describing a situation in which you have a collection of objects and you want a sub collection of objects that satisfy some criteria (in your case the criteria is “an object’s attribute slot is empty"). So, first, just apply a #select: message to the persistent collection. Would that be semantically the same? If so, are you eliminating that solution based on a measurable performance concern? One way to think about concurrency is how the events would play out if they were not in parallel, but happened in series (e.g., with a lock on the persistent collection). If the object changed so that it satisfied the condition before the purge runs, then the object stays. If the purge runs first, how does the object get added back? Is a new object created? Or is it in another collection? If the object would be persistent anyway (in another collection), then, again, why not a #select: on the main collection? If that has a measurable performance problem then look at creating an index on the attribute in question and use the index-based #select: method. Again, I’m asking mostly to better understand the question, not to push a solution on you. James
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by GLASS mailing list
Marten,
It sounds like you're describing a condition where there is a semantic conflict, even when the conflicting sessions do not commit changes to the same object. In order for GemStone to report a transaction conflict in cases like that, you need to have both sessions modify the same object. I will refer to this object as the "conflict object." This could be one of the objects you already have, or you might have to create it just for that purpose, depending on the situation. If I understand what you've described correctly, you have an overall collection holding objects. Each object holds a set of attributes. You want a transaction removing the object from the overall collection to conflict with a transaction adding an attribute. If this is an accurate description of your situation, one choice would be to use the object itself as the "conflict object." If you modify the object every time you add an attribute to it, and also modify the object when it's removed from the collection, then concurrent transactions doing those operations will conflict. IIRC, modifying an object by assigning an instvar to itself like someInstVar := someInstVar. is sufficient for the object to be considered written for the purposes of transaction conflict detection. By using this kind of pattern, these cases *can* be handled. But when you run into these cases, it's worthwhile to examine your overall architecture to see whether there's a change that would avoid needing this kind of complexity, since code acquires a certain amount of fragility when it's required to use these patterns. Regards, -Martin _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Free forum by Nabble | Edit this page |