[GODRIVER-1721] (NoSuchTransaction) Transaction 1 has been aborted. Created: 17/Aug/20  Updated: 27/Oct/23  Resolved: 21/Aug/20

Status: Closed
Project: Go Driver
Component/s: CRUD
Affects Version/s: 1.3.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: 汇嘉 庄 Assignee: Isabella Siu (Inactive)
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related

 Description   

My Aim: In a transaction, I want to replace a doc manually instead of aborting the transaction automatically after inserting a doc failed because of `duplicate key error`.

The `insert or replace code` shows like below:

 

// InsertContract insert contract
func InsertContract(ctx context.Context, contract *models.Contract) (err error) {
   ...
   res, err = collection.InsertOne(c, contract)
   if err != nil {
      log.Error("insert one contract error:%+v, result:%+v", err, res)
      if strings.Contains(err.Error(), consts.MongoDocumentExisted) {
         filter = findOneContractFilter(contract.ContractId, contract.ProductId)
         _, err = collection.ReplaceOne(c, filter, contract)
         if err != nil {
            log.Error("replace after insert one contract error:%+v, filter:%+v", err, *filter)
         }
      }
      return
   }
   ...
   return
}

The transaction code shows like below:

 

 

if transaction := config.Pool.UseSessionWithOptions(ctx, &options.SessionOptions{
   CausalConsistency:     &options.DefaultCausalConsistency,
   DefaultReadPreference: readpref.Primary(),
}, func(sessionContext mongo.SessionContext) error {
   // start session
   if err = sessionContext.StartTransaction(); err != nil {
      return err
   }
   if err = mypkg.InsertContract(sessionContext, contract); err != nil {
      return sessionContext.AbortTransaction(sessionContext)
   }
....

But it doesn't work.

 

The log print below: 

[E] insert one contract error:multiple write errors: [{write errors: [{E11000 duplicate key error collection: ...
[E] replace after insert one contract error:(NoSuchTransaction) Transaction 1 has been aborted....

The Transaction always aborts automatically, cause that I cannot replace the doc manually.

 



 Comments   
Comment by Isabella Siu (Inactive) [ 21/Aug/20 ]

Hi 1150555483@qq.com,

If any operation in a transaction fails, the server will abort the transaction automatically. https://docs.mongodb.com/manual/core/transactions/#transactions-and-atomicity If upsert doesn't work for your use case, you could start with a FindOne instead of the InsertOne to check if the document already exists instead.

Generated at Thu Feb 08 08:36:59 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.