1 回答

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