Details
-
Bug
-
Resolution: Fixed
-
Major - P3
-
None
-
None
-
None
-
Not Needed
Description
version: 1.5.2
I use a context with a short timeout, and find WithTransaction method will be stuck in a endless loop
Here is my code:
client, err := mongo.NewClient()
|
if err != nil { |
return |
}
|
|
|
err = client.Connect(context.Background())
|
if err != nil { |
return |
}
|
s, err := client.StartSession()
|
if err != nil { |
return |
}
|
_, err = s.WithTransaction(context.Background(), func(ctx mongo.SessionContext) (interface{}, error) { |
c, cancel := context.WithTimeout(ctx, time.Nanosecond)
|
defer cancel()
|
|
|
// infinite loop |
_, err = client.Database("xxx"). |
Collection("xxx"). |
InsertOne(c, nil)
|
if err != nil { |
return nil, err |
}
|
|
|
return nil, nil |
})
|
if err != nil { |
return |
}
|
The InsertOne method will return the following error:
connection(xxxx) failed to write: context deadline exceeded
|
The error has TransientTransactionError and NetworkError label, so it make WithTransaction method stuck in an infinite loop
for { |
err = s.StartTransaction(opts...)
|
if err != nil { |
return nil, err |
}
|
|
|
res, err := fn(NewSessionContext(ctx, s))
|
if err != nil { |
if s.clientSession.TransactionRunning() { |
// Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and |
// cancellations, but forwards Value requests to the original one. |
_ = s.AbortTransaction(internal.NewBackgroundContext(ctx))
|
}
|
|
|
select {
|
case <-timeout.C: |
return nil, err |
default: |
}
|
|
|
if errorHasLabel(err, driver.TransientTransactionError) { |
continue |
}
|
return res, err |
}
|
}
|
Attachments
Issue Links
- related to
-
GODRIVER-2468 Don't check Context expiration in WithTransaction
-
- Closed
-
-
DRIVERS-1753 Allow configurable WithTransaction timeout
-
- Closed
-