Open wxf4150 opened 6 years ago
What you’re describing here is just the nature of concurrency. I wouldn’t really call this a bug.
If you find yourself saving the same document in multiple different go routines then you probably just need to address that in your application architecture. Can you explain the use case?
Sent via Mobile
From: wxf4150 notifications@github.com Sent: Tuesday, May 29, 2018 3:51:08 AM To: go-bongo/bongo Cc: Subscribed Subject: [go-bongo/bongo] Collection.Save CascadeSave bug (#36)
Collection.Save(document) method invoke "CascadeSave" using goRoutine. when i change document's field 10 times and save every times. the function CascadeSave will invoke 10 times use 10 Routines; the 10 Routines will not ordered, some Routines will concurrency, then parent doc error
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/go-bongo/bongo/issues/36, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AEXD4tsXWMQ_doIkUxOrbjPYruRXYm3jks5t3P3sgaJpZM4UQ_sD.
var parentColl *bongo.Collection
var childColl *bongo.Collection
type parent struct{
bongo.DocumentBase `bson:",inline"`
Childs []*Child
}
type Child struct{
bongo.DocumentBase `bson:",inline"`
ParentID bson.ObjectId
Status int
diffTracker *bongo.DiffTracker
}
func Test_Bongo(t *testing.T){
parentColl=utils.Bconn.Collection("parent")
childColl=utils.Bconn.Collection("child")
parent:=new(parent)
parentColl.Save(parent)
child:=new(Child)
child.ParentID=parent.Id
childColl.Save(child)
for i:=1;i<100;i++{
child.Status=i
childColl.Save(child) //will invoke CascadeSave using (goroutine CascadeSave)
//code: https://github.com/go-bongo/bongo/blob/master/collection.go#L147
}
//**the end**: len(parent.Childs)!=1 or parent.Childs[0].Status!=99
}
func (c *Child) GetCascade(collection *bongo.Collection) []*bongo.CascadeConfig {
connection := collection.Connection
rel :=c
cascadeMulti := &bongo.CascadeConfig{
Collection: connection.Collection("parent"),
//Properties: []string{"name","orgname","status"},
Data:rel,
ThroughProp: "childs",
RelType: bongo.REL_MANY,
Query: bson.M{
"_id": c.ParentID,
},
}
if c.diffTracker!=nil && c.diffTracker.Modified("ParentID") {
origId, _ := c.diffTracker.GetOriginalValue("ParentID")
if origId != nil {
oldQuery := bson.M{
"_id": origId,
}
cascadeMulti.OldQuery = oldQuery
}
}
return []*bongo.CascadeConfig{ cascadeMulti}
}
the end: parent doccument error, len(parent.Childs)!=1 or parent.Childs[0].Status!=99
or update this way
for i:=1;i<20;i++{
cloneChild:=*child
cloneChild.Status=i
childColl.Save(&cloneChild)
}
time.Sleep(2*time.Second)
the end: parent doccument error, len(parent.Childs)!=1 or parent.Childs[0].Status!=19
I could see this being a race condition if there are multiple users updating the same record. Solution seems to be just removing the go
in front of the CascadeSave
here https://github.com/go-bongo/bongo/blob/master/collection.go#L147
Can you submit a PR?
Collection.Save(document) method invoke "CascadeSave" using goRoutine. when i change document's field 10 times and save every times. the function CascadeSave will invoke 10 times use 10 Routines; the 10 Routines will not ordered, some Routines will concurrency, then parent doc error