#1382705 forbid with sql level locking the simultaneous fireing of a transition on a given entity
--- a/hooks/workflow.py Mon Jan 03 11:22:32 2011 +0100
+++ b/hooks/workflow.py Tue Dec 21 21:20:19 2010 +0100
@@ -191,6 +191,8 @@
msg = session._('mandatory relation')
raise ValidationError(entity.eid, {qname: msg})
forentity = session.entity_from_eid(foreid)
+ # see comment in the TrInfo entity definition
+ entity.cw_edited['tr_count']=len(forentity.reverse_wf_info_for)
iworkflowable = forentity.cw_adapt_to('IWorkflowable')
# then check it has a workflow set, unless we're in the process of changing
# entity's workflow
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.10.7_Any.py Tue Dec 21 21:20:19 2010 +0100
@@ -0,0 +1,2 @@
+add_attribute('TrInfo', 'tr_count')
+sync_schema_props_perms('TrInfo')
--- a/schemas/workflow.py Mon Jan 03 11:22:32 2011 +0100
+++ b/schemas/workflow.py Tue Dec 21 21:20:19 2010 +0100
@@ -22,7 +22,7 @@
_ = unicode
from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
- RichString, String)
+ RichString, String, Int)
from cubicweb.schema import RQLConstraint, RQLUniqueConstraint
from cubicweb.schemas import (META_ETYPE_PERMS, META_RTYPE_PERMS,
HOOKS_RTYPE_PERMS)
@@ -159,13 +159,21 @@
'delete': (), # XXX should we allow managers to delete TrInfo?
'update': ('managers', 'owners',),
}
-
- from_state = SubjectRelation('State', cardinality='1*')
- to_state = SubjectRelation('State', cardinality='1*')
+ # The unique_together constraint ensures that 2 repositories
+ # sharing the db won't be able to fire a transition simultaneously
+ # on the same entity tr_count is filled in the FireTransitionHook
+ # to the number of TrInfo attached to the entity on which we
+ # attempt to fire a transition. In other word, it contains the
+ # rank of the TrInfo for that entity, and the constraint says we
+ # cannot have 2 TrInfo with the same rank.
+ __unique_together__ = [('tr_count', 'wf_info_for')]
+ from_state = SubjectRelation('State', cardinality='1*', inlined=True)
+ to_state = SubjectRelation('State', cardinality='1*', inlined=True)
# make by_transition optional because we want to allow managers to set
# entity into an arbitrary state without having to respect wf transition
by_transition = SubjectRelation('BaseTransition', cardinality='?*')
comment = RichString(fulltextindexed=True)
+ tr_count = Int(description='autocomputed attribute used to ensure transition coherency')
# get actor and date time using owned_by and creation_date
class from_state(RelationType):