gpt4 book ai didi

npgsql - Npgsql 提供程序是否支持 TransactionScope?

转载 作者:行者123 更新时间:2023-12-04 14:57:08 24 4
gpt4 key购买 nike

我正在尝试将 TransactionScope 与 Npgsql 提供程序一起使用。
我在一个旧问题 ( provider for PostgreSQL in .net with support for TransactionScope ) 中发现 Npgsql 还不支持它。
现在,大约 5 年后,Npgsql 是否支持 TransactionScope?
我为自己做了一个测试,使用 Npgsql 3.0.3 并使用以下代码:

using (var scope = new TransactionScope())
{
using(var connection = new Npgsql.NpgsqlConnection("server=localhost;user id=*****;password=*****database=test;CommandTimeout=0"))
{
connection.Open();

var command = new NpgsqlCommand(@"insert into test.table1 values ('{10,20,30}', 2);");
command.Connection = connection;
var result = command.ExecuteNonQuery();

// scope.Complete(); <-- Not committed
}
}

任何人都可以确认 Npgsql 不支持 TransactionScope?

编辑 #1
确认Npgsql对TransactionScope的支持后,我发现你需要确保在你的PostgreSQL配置中启用了分布式事务,检查postgres.conf文件中的max_prepared_transactions参数(记得重启你的服务器)。

编辑 #2
我在我的服务器上启用了分布式事务,但现在我在使用 TransactionScope 和 Npgsql 时遇到错误。
这是我的代码:
using (var sourceDbConnection = new NpgsqlConnection(SourceConnectionString))
using (var destinationDbConnection = new NpgsqlConnection(DestinationConnectionString))
using (var scope = new TransactionScope())
{
sourceDbConnection.Open();
destinationDbConnection.Open();

Logger.Info("Moving data for the {0} table.", TableName.ToUpper());
var innerStopWatch = new Stopwatch();
innerStopWatch.Start();

foreach (var entity in entities)
{
var etlEntity = new EtlInfoItem
{
MigratedEntityId = category.RowId,
ProjectId = category.ProjectId,
ExecutionDatetime = DateTime.Now
};

// Insert into the destination database
var isRowMigrated = InsertEntity(entity, DestinationSchema, destinationDbConnection);

if (isRowMigrated)
{
// Update the ETL migration table
InsertCompletedEtlMigrationEntity(etlEntity, EtlSchema, sourceDbConnection);
}
else
{
// Update the ETL migration table
InsertFailedEtlMigrationEntity(etlEntity, EtlSchema, sourceDbConnection);
}
}

Logger.Info("Data moved in {0} sec.", innerStopWatch.Elapsed);

Logger.Info("Committing transaction to the source database");
innerStopWatch.Restart();

scope.Complete();

innerStopWatch.Stop();
Logger.Info("Transaction committed in {0} sec.", innerStopWatch.Elapsed);
}

当 TransactionScope 从作用域中退出时(退出 using 语句时),我得到一个空引用异常,并带有以下堆栈跟踪:
服务器堆栈跟踪:
在 Npgsql.NpgsqlConnector.Cleanup()
在 Npgsql.NpgsqlConnector.Break()
在 Npgsql.NpgsqlConnector.ReadSingleMessage(DataRowLoadingMode dataRowLoadingMode, Boolean returnNullForAsyncMessage)
在 Npgsql.NpgsqlConnector.ReadExpectingT
…………
它是随机发生的。

最佳答案

Npgsql 确实支持 TransactionScope,并且已经这样做了一段时间。但是,至少目前,为了让您的连接参与 TransactionScope,您必须:

  • 包含 Enlist=true在您的连接字符串中,或​​
  • 调用 NpgsqlConnection.EnlistTransaction

  • 看看 Npgsql unit tests围绕这个一些例子。

    关于npgsql - Npgsql 提供程序是否支持 TransactionScope?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33588232/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com