1
0
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:
Gani Georgiev 2022-12-18 11:11:34 +02:00
parent 84ba89d5af
commit bd16680548
3 changed files with 63 additions and 2 deletions

View File

@ -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).

View File

@ -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")

View File

@ -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()