1 回答

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個(gè)贊
這里的第一個(gè)問(wèn)題可能掩蓋了實(shí)際的根本原因,即您沒(méi)有檢查是否INSERT返回錯(cuò)誤。你會(huì)這樣做:
result := tx.Create(&temp)
if result.Error != nil {
// handle it somehow
}
如果你這樣做并檢查錯(cuò)誤,你可能會(huì)看到一些東西:
錯(cuò)誤:重復(fù)鍵值違反唯一約束
即使您還看到以下錯(cuò)誤,您也可能會(huì)看到這一點(diǎn)。在這種情況下,您的 INSERT 正在執(zhí)行,但失敗了。如果您沒(méi)有看到任何其他錯(cuò)誤并且只打印一次,那么您可能傳入了一個(gè) gorm.DB 句柄,該句柄已鏈接到數(shù)據(jù)庫(kù)會(huì)話,并且會(huì)在第一個(gè)錯(cuò)誤時(shí)失敗。
例如,如評(píng)論中所述,如果將結(jié)果傳遞db.Table("my_table")給此方法,則將出現(xiàn)上述情況。要修復(fù)它,只需傳遞db或db.NewSession(),并更新您的方法以指定表(或模型,更像 Gorm):
result := db.Table("my_table_name").Create(&temp)
if result.Error != nil {
// ...
}
選項(xiàng) 2:錯(cuò)誤:當(dāng)前事務(wù)被中止,命令被忽略,直到事務(wù)塊結(jié)束
如果您看到這一點(diǎn),則意味著您的方法正在事務(wù)中運(yùn)行它的插入。這對(duì)你來(lái)說(shuō)并非如此,但由于這是一個(gè)通用論壇,我將在此處留下這個(gè)和下面的解釋?zhuān)涸?Postgres 中,如果任何語(yǔ)句在事務(wù)中失敗,你不能執(zhí)行任何進(jìn)一步的語(yǔ)句,除了 ROLLBACK .
要解決此問(wèn)題,您有幾種選擇:
在嘗試插入之前進(jìn)行更多的數(shù)據(jù)驗(yàn)證,直到您可以可靠地預(yù)期每次插入都會(huì)成功。您還可以使用 Gorm 的批量插入功能通過(guò)這種方法優(yōu)化插入。
不要使用事務(wù)。如果您可以接受跳過(guò)的行,并且不擔(dān)心重復(fù),那么這是一個(gè)合理的選擇。
使用保存點(diǎn)。在 Postgres 中,SAVEPOINT 類(lèi)似于事務(wù)中的檢查點(diǎn),您可以回滾到它而不是回滾整個(gè)事務(wù),這正是您想要的:
tx.SavePoint("sp1") // SAVEPOINT sp1;
result := tx.Create(&temp)
if result.Error != nil {
tx.RollbackTo("sp1") // ROLLBACK TO sp1;
}
- 1 回答
- 0 關(guān)注
- 482 瀏覽
添加回答
舉報(bào)