我正在使用mongo-go-driver0.0.18构建一个由"NewUpdateManyModel“和几个"NewInsertOneModel”组成的批量写入程序。我的mongo服务器是带有副本集的地图集M10。我构建了一些goroutines来测试事务是否是原子的,结果显示每个批量写入都不是原子的,它们会相互干扰。我想知道芒果驱动程序是否支持多文档交易?
func insertUpdateQuery(counter int, col *mongo.Collection, group *sync.WaitGroup){
var operations []mongo.WriteModel
var items = []item{}
items=append(items,item{"Name":strconv.Itoa(counter),"Description":"latest one"})
for _,v := range items{
operations = append(operations, mongo.NewInsertOneModel().Document(v))
}
updateOperation := mongo.NewUpdateManyModel()
updateOperation.Filter(bson.D{
{"Name", bson.D{
{"$ne", strconv.Itoa(counter)},
}},
})
updateOperation.Update(bson.D{
{"$set", bson.D{
{"Description", strconv.Itoa(counter)},
}},
},)
operations = append(operations,updateOperation)
bulkOps:=options.BulkWrite()
result, err := col.BulkWrite(
context.Background(),
operations,
bulkOps,
)
if err != nil{
fmt.Println("err:",err)
}else{
fmt.Printf("IU: %+v \n",result)
}
group.Done()
}
func retrieveQuery(group *sync.WaitGroup, col *mongo.Collection){
var results []item
qctx:=context.Background()
qctx, c := context.WithTimeout(qctx, 10*time.Second)
defer c()
cur, err := col.Find(qctx, nil)
if err != nil {
log.Fatal(err)
}
defer cur.Close(context.Background())
res := item{}
for cur.Next(context.Background()) {
err := cur.Decode(&res)
if err != nil {
log.Println(err)
}else {
results=append(results,res)
}
}
if err := cur.Err(); err != nil {
log.Println(err)
}
fmt.Println("res:",results)
group.Done()
}
func main() {
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx,10*time.Second)
defer cancel()
uri := "..."
client, err := mongo.NewClient(uri)
if err != nil {
fmt.Printf("todo: couldn't connect to mongo: %v", err)
}
defer cancel()
err = client.Connect(ctx)
if err != nil {
fmt.Printf("todo: mongo client couldn't connect with background context: %v", err)
}
col:=client.Database("jistest").Collection("Rules")
wg :=&sync.WaitGroup{}
for i:=0; i<100; i++{
wg.Add(2)
go insertUpdateQuery(i,col,wg)
go retrieveQuery(wg,col)
}
wg.Wait()
fmt.Println("All Done!")
}发布于 2018-12-10 03:16:14
我想知道芒果驱动程序是否支持多文档交易?
蒙戈支持多文档事务,因为v0.0.12 (目前处于beta版本0.1.0)。
MongoDB多文档事务与会话相关联。也就是说,您为会话启动事务。当使用任何MongoDB官方支持的驱动程序时,必须将会话传递给事务中的每个操作。
您的示例似乎没有使用会话或事务。mongo-go驱动程序(v0.1.0)中的多文档事务示例如下:
client, err := mongo.NewClient("<MONGODB URI>")
if err != nil { return err }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil { return err }
session, err := client.StartSession()
database := client.Database("databaseName")
collection := database.Collection("collectionName")
err = mongo.WithSession(ctx, session, func(sctx mongo.SessionContext) error {
// Start a transaction in the session
sctx.StartTransaction()
var operations []mongo.WriteModel
// Create an insert one operation
operations = append(operations,
mongo.NewInsertOneModel().Document(
bson.D{{"Name", counter},
{"Description", "latest"}}))
// Create an update many operation
updateOperation := mongo.NewUpdateManyModel()
updateOperation.Filter(bson.D{{"Name", bson.D{
{"$ne", counter},
}}})
updateOperation.Update(bson.D{
{"$set", bson.D{
{"Description", counter},
}},
})
operations = append(operations, updateOperation)
// Execute bulkWrite operation in a transactional session.
_, err := collection.BulkWrite(sctx, operations)
if err != nil {
fmt.Println(err)
return err
}
// Committing transaction
session.CommitTransaction(sctx)
return nil
})
session.EndSession(ctx)有关重试事务的示例,请参见事务和可还原写入。
我构建了一些goroutine来测试这些事务是否是原子的。
只需注意进程是如何执行的。例如,根据赛车的情况,您可能会得到最新的性能覆盖结果。即
transaction 1 finished
transaction 2 finished
transaction 3 and transaction 4 conflict
transaction 5 finished
... https://stackoverflow.com/questions/53621036
复制相似问题