Golang中从数据库删除数据后无法重新插入到同一表的问题

Golang中从数据库删除数据后无法重新插入到同一表的问题 我遇到了一个奇怪的问题,从数据库表中删除数据后,无法再次向同一表插入数据。

以下是一个示例:

_, err = con.Query(`
	DELETE FROM loan_aims WHERE _loan = $1;
`, input.ID)
if err != nil {
	tx.Rollback()
	log.Println(err)
	return false, fmt.Errorf("can not delete additional data from loan_aims")
}

stmtAim, err := con.Prepare(`INSERT INTO loan_aims(_loan,_aim) VALUES ($1,$2)`)
if err != nil {
	tx.Rollback()
	log.Println(err)
	return false, fmt.Errorf("can not insert into loan_aims")
}

 for i := 0; i < len(aims); i++ {
	_, err := stmtAim.Exec(loanID, aims[i])

	if err != nil {
		tx.Rollback()
		return false, fmt.Errorf("can not insert aim 2")
	}
}

这个方法不起作用,我的数据库中的loan_aims表保持为空,但如果我移除以下代码:

_, err = con.Query(`
DELETE FROM loan_aims WHERE _loan = $1;
`, input.ID)
 if err != nil {
     tx.Rollback()
         log.Println(err)
     return false, fmt.Errorf("can not delete additional data from loan_aims")
}

它就能正常工作,顺便说一下,我使用的是PostgreSQL。


更多关于Golang中从数据库删除数据后无法重新插入到同一表的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你所说的"它不工作"是什么意思?是否有任何错误返回?

更多关于Golang中从数据库删除数据后无法重新插入到同一表的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个典型的数据库事务处理问题。问题在于您在同一个事务中混合使用了con.Query()con.Prepare(),这可能导致语句在事务中的执行顺序或连接状态出现问题。

以下是修正后的代码:

// 使用事务的Exec方法来执行DELETE
_, err = tx.Exec(`DELETE FROM loan_aims WHERE _loan = $1`, input.ID)
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not delete additional data from loan_aims")
}

// 在同一个事务中准备INSERT语句
stmtAim, err := tx.Prepare(`INSERT INTO loan_aims(_loan,_aim) VALUES ($1,$2)`)
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not insert into loan_aims")
}
defer stmtAim.Close()

for i := 0; i < len(aims); i++ {
    _, err := stmtAim.Exec(loanID, aims[i])
    if err != nil {
        tx.Rollback()
        return false, fmt.Errorf("can not insert aim 2")
    }
}

// 提交事务
err = tx.Commit()
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not commit transaction")
}

关键修改点:

  1. 使用tx.Exec()而不是con.Query()来执行DELETE操作,确保操作在事务范围内
  2. 使用tx.Prepare()而不是con.Prepare()来准备INSERT语句
  3. 添加了defer stmtAim.Close()来确保语句正确关闭
  4. 在循环结束后明确提交事务

如果问题仍然存在,可以尝试不使用预处理语句的简化版本:

// 执行DELETE
_, err = tx.Exec(`DELETE FROM loan_aims WHERE _loan = $1`, input.ID)
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not delete additional data from loan_aims")
}

// 直接执行INSERT
for i := 0; i < len(aims); i++ {
    _, err := tx.Exec(`INSERT INTO loan_aims(_loan,_aim) VALUES ($1,$2)`, loanID, aims[i])
    if err != nil {
        tx.Rollback()
        return false, fmt.Errorf("can not insert aim 2")
    }
}

err = tx.Commit()
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not commit transaction")
}

这样可以避免预处理语句可能带来的连接状态问题。

回到顶部