mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-25 09:21:11 +02:00
[#1291] fixed nested tx deadlock when creating new user with OAuth2
This commit is contained in:
parent
84ba89d5af
commit
bd16680548
@ -1,3 +1,8 @@
|
|||||||
|
## v0.10.1
|
||||||
|
|
||||||
|
- Fixed nested transactions deadlock when authenticating with OAuth2 ([#1291](https://github.com/pocketbase/pocketbase/issues/1291)).
|
||||||
|
|
||||||
|
|
||||||
## v0.10.0
|
## v0.10.0
|
||||||
|
|
||||||
- Added `/api/health` endpoint (thanks @MarvinJWendt).
|
- Added `/api/health` endpoint (thanks @MarvinJWendt).
|
||||||
|
@ -675,9 +675,10 @@ func (form *RecordUpsert) DrySubmit(callback func(txDao *daos.Dao) error) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the default app.Dao to prevent changing the transaction form.Dao
|
// use the default app.Dao().ConcurrentDB() to prevent changing the transaction form.Dao
|
||||||
// and causing "transaction has already been committed or rolled back" error
|
// and causing "transaction has already been committed or rolled back" error
|
||||||
return form.app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
|
dryDao := daos.New(form.app.Dao().ConcurrentDB())
|
||||||
|
return dryDao.RunInTransaction(func(txDao *daos.Dao) error {
|
||||||
tx, ok := txDao.DB().(*dbx.Tx)
|
tx, ok := txDao.DB().(*dbx.Tx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("failed to get transaction db")
|
return errors.New("failed to get transaction db")
|
||||||
|
@ -337,6 +337,61 @@ func TestRecordUpsertDrySubmitSuccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecordUpsertDrySubmitWithNestedTx(t *testing.T) {
|
||||||
|
app, _ := tests.NewTestApp()
|
||||||
|
defer app.Cleanup()
|
||||||
|
|
||||||
|
collection, _ := app.Dao().FindCollectionByNameOrId("demo1")
|
||||||
|
recordBefore, err := app.Dao().FindRecordById(collection.Id, "84nmscqy84lsi1t")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
formData, mp, err := tests.MockMultipartData(map[string]string{
|
||||||
|
"title": "dry_test",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txErr := app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
|
||||||
|
form := forms.NewRecordUpsert(app, recordBefore)
|
||||||
|
form.SetDao(txDao)
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/", formData)
|
||||||
|
req.Header.Set(echo.HeaderContentType, mp.FormDataContentType())
|
||||||
|
form.LoadRequest(req, "")
|
||||||
|
|
||||||
|
callbackCalls := 0
|
||||||
|
|
||||||
|
result := form.DrySubmit(func(innerTxDao *daos.Dao) error {
|
||||||
|
callbackCalls++
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if result != nil {
|
||||||
|
t.Fatalf("Expected nil, got error %v", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure callback was called
|
||||||
|
if callbackCalls != 1 {
|
||||||
|
t.Fatalf("Expected callbackCalls to be 1, got %d", callbackCalls)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure that the record changes weren't persisted
|
||||||
|
recordAfter, err := app.Dao().FindRecordById(collection.Id, recordBefore.Id)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if recordAfter.GetString("title") == "dry_test" {
|
||||||
|
t.Fatalf("Expected record.title to be %v, got %v", recordAfter.GetString("title"), "dry_test")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if txErr != nil {
|
||||||
|
t.Fatalf("Nested transactions failure: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRecordUpsertSubmitFailure(t *testing.T) {
|
func TestRecordUpsertSubmitFailure(t *testing.T) {
|
||||||
app, _ := tests.NewTestApp()
|
app, _ := tests.NewTestApp()
|
||||||
defer app.Cleanup()
|
defer app.Cleanup()
|
||||||
|
Loading…
Reference in New Issue
Block a user