You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Begin Transaction Rollback:多Insert/Update事务异常回滚范围及重复键报错咨询

问题解答

异常发生时的回滚范围

在你提供的代码逻辑中,所有未提交的操作会被全部回滚,不会只回滚出错的单条语句。原因如下:

  • 代码通过conn.BeginTransaction()开启了一个数据库事务,所有后续的SQL操作都属于这个事务的范围。
  • 不管strQueryBuild中拼接了多少条INSERT/UPDATE语句,只要ExecuteNonQuery执行过程中任何一条语句抛出异常(比如重复键冲突),整个执行会中断并进入catch块,调用tra.Rollback()会撤销事务内的所有操作,数据库状态回到事务开启前的样子。

关于重复键冲突(duplicate key violation)错误

你再次执行时遇到这个错误,是因为你要插入的数据中,主键或唯一约束字段的值和数据库中已存在的记录重复了。需要注意:

  • 第一次执行时事务回滚,意味着之前的操作没有被持久化到数据库,但如果第二次执行的仍然是包含重复键的相同数据,自然会触发PostgreSQL的唯一约束校验,抛出该错误。
  • 解决思路可以是:
    • 插入前先查询数据库,判断该键是否已存在,避免重复插入
    • 使用PostgreSQL的ON CONFLICT语法,在插入遇到冲突时执行更新或忽略操作(比如INSERT INTO sales(...) VALUES(...) ON CONFLICT (id) DO NOTHING)

你的代码片段

using (var conn = new NpgsqlConnection(connstr))
{
    conn.Open();
    var tra = conn.BeginTransaction();
    try
    {
        NpgsqlCommand cmd = new NpgsqlCommand();
        cmd.Connection = conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandTimeout = 0;
        cmd.CommandText = strQueryBuild.ToString();
        RowsAffected = cmd.ExecuteNonQuery();
        tra.Commit();
        commitstatus = true;
    }
    catch (Exception ex)
    {
        commitstatus = false;
        AppHelper.ErrrorLog(ex, "UploadFileData-Error1");
        RowsAffected = -1;
        tra.Rollback();
    }
    
}

内容的提问来源于stack exchange,提问作者Manjay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:37:07