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 关注
- 409 浏览
添加回答
举报