Npgsql 如何处理失败的事务?

pao*_*_tn 6 c# postgresql npgsql sqltransaction

在 ASP.NET 应用程序 (C#) 中,我们使用 Postgres 作为后端,使用 Npgsql 作为数据提供者。几天前,我们遇到了数据丢失的严重问题。我在代码中进行了调查,发现了这样的代码:

    var transaction = connection.BeginTransaction();
    //some crud operation here  
    transaction.Commit()
Run Code Online (Sandbox Code Playgroud)

有人坚持认为 Npgsql 会自行处理异常,并会在事务过程中出现问题时自动回滚事务。

在我看来,这是非常乐观的,代码应该包含在 try 和 catch 块中并显式调用事务回滚:

 var transaction = connection.BeginTransaction();
 try
    {
        //some crud operation here        
        transaction.Commit
    }catch(Exception ex)
    {
        transaction.Rollback();
    }
Run Code Online (Sandbox Code Playgroud)

错了吗?

此外,事务回滚总是有效吗?我在某处读到它只有在引发 Postgres 异常时才有效,比如在格式错误的 sql 的情况下,但在其他类型的异常的情况下它不起作用。有人也可以澄清这一点吗?

Lau*_*lbe 6

如果出现错误,PostgreSQL 将自动中止事务,但不会回滚。

仅当您满足以下条件时,交易才会完成

  1. 断开

  2. COMMIT用或结束事务(两种ROLLBACK情况都会回滚)

在错误和事务结束之间的连接上发送的所有语句都将被忽略。

所以是的,您应该使用try/catch块并回滚。

AROLLBACK总是会完全撤消当前事务,无论是否有错误。


Fra*_*sen 6

另一种方式可能是:

using( var tx = connection.BeginTransaction())
{
    .. do som database stuff ..

    tx.Commit();
}
Run Code Online (Sandbox Code Playgroud)

处理未提交的事务会导致回滚。并且资源被释放!

  • https://github.com/npgsql/npgsql/blob/main/src/Npgsql/NpgsqlTransaction.cs#L366-L389 应标记为接受的答案。 (2认同)