0

我有一个数据库类,其方法如下所示。两者foobar都是全有或全无的操作。因此需要交易。请注意,我将MySQL5.5.21 与MySQL .NET Connector 6.6.4.

public void foo()
{
    using (var transaction = new TransactionScope())
    {
        // This call yields a 'System.Transactions.TransactionException'
        bar();

        insertStuff();

        transaction.Complete();
    }
}

public void bar()
{
    using (var transaction = new TransactionScope())
    {
        insertStuff();
        insertStuff();

        transaction.Complete();
    }
}

private void insertStuff()
{
    using (var connection = CreateConnection()) // Using the same connection string!
    {
        connection.ConnectionString = ConnectionString;
        connection.Open();
    }
}

我确实尝试TransactionScopeOption.RequiresNew在构造函数中指定,但没有帮助。我还尝试在每个事务范围之前显式打开一个连接,但仍然没有成功。

我想要的是这样的:

  • 如果我一个bar人打电话,应该有一笔交易。
  • 如果我打电话foo(反过来打电话bar),应该有一笔交易。

问:我是否面临限制MySQL .NET Connector或我做错了什么?

编辑:确切的错误是:该操作对事务状态无效。 所以,一旦我调用Open()连接,交易就会退出......

4

2 回答 2

0

最有可能的是,您正在打开 2 个或更多与数据库的连接,并且在事务范围内,MSDTC 被调用。通常,如果您想要一个事务,您将创建连接,然后将其传递给每个操作。这将确保您始终在同一连接上进行更改。如果您有 2 个连接,则必须协调每个连接上的更改。

但是,如果您提供更多异常消息,则可能会更清楚原因。

于 2012-11-12T09:07:08.303 回答
0

使用 bar 如图所示:

public void bar()
{
        insertStuff();
        insertStuff();
}

工作吗?

为获得最佳实践,您可以使用 IDbConnection.BeginTransaction() 创建事务,因为事务是连接范围的。

public void foo()
{
    using(IDbConnection connection = new MySqlConnection(/*connection string*/))
    {
        connection.Open();
        using(IDbTransction transaction = connection.BeginTransaction())
        {
            bar(connection);
            insertStuff(connection);

            transaction.Commit();
        }

    }
}

public void bar(IDbConnection connection)
{
        insertStuff(connection);
        insertStuff(connection);
}

private void insertStuff(IDbConnection connection)
{
     // do stuff
}
于 2012-11-12T09:22:52.027 回答