SubSonic: MySqlDataReader закрывает соединение - PullRequest
0 голосов
/ 02 июня 2010

Я использую SubSonic 2.1 и столкнулся с проблемой при выполнении транзакции с

SharedDbConnectionScope и TransactionScope. Проблема в том, что в методе obj.Save () я получаю исключение «Соединение должно быть действительным и открытым»

Я отследил проблему до этой строки:

// Loads a SubSonic ActiveRecord object
User user = new User(User.Columns.Username, "John Doe");

в этом конструкторе класса User вызывается метод "LoadParam", который в конечном итоге делает

if (rdr != null)
    rdr.Close();

Похоже, что rdr.Close () неявно закрывает мое соединение, что нормально при использовании AutomaticConnection. Но во время транзакции обычно не рекомендуется закрывать соединение :-)

У меня вопрос, если это специально или это ошибка в MySqlDataReader.

1 Ответ

0 голосов
/ 02 июня 2010

Это было сложно! После небольшой отладки я нашел следующий метод в файле SubSonic2 MySqlDataReader.cs:

    public override IDataReader GetReader(QueryCommand qry)
    {
        AutomaticConnectionScope conn = new AutomaticConnectionScope(this);

        ...

        cmd.Connection = (MySqlConnection)conn.Connection;

        IDataReader rdr;

        try
        {
            rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
        catch(MySqlException x)
        {
            conn.Dispose();
            throw x;
        }

        ...
    }

Что не так, поскольку я использую SharedDbConnection. В SqlDataProvider это уже исправлено, но не для MySqlDataReader.

Это должно выглядеть так:

        try
        {
            // if it is a shared connection, we shouldn't be telling the reader to close it when it is done
            rdr = conn .IsUsingSharedConnection ?
                      cmd.ExecuteReader() : 
                      cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
        catch (MySqlException)
        {
            // AutoConnectionScope will figure out what to do with the connection
            conn.Dispose();
            //rethrow retaining stack trace.
            throw;
        }

Довольно тяжелый баг, из-за которого нельзя было запрашивать запросы в транзакции (должен признать, что раньше мне это никогда не требовалось).

...