Subsonic: Mysqldatareader закрывает соединение
-
23-10-2019 - |
Вопрос
Я использую oofonic 2.1 и внедрил проблему во время выполнения транзакции с
Shareddbconnectionscope и transactionScope. Проблема в том, что в методе obj.save () я получаю «соединение должно быть действительным и открытым» исключением
Я отследил проблему до этой линии:
// Loads a SubSonic ActiveRecord object
User user = new User(User.Columns.Username, "John Doe");
В этом конструкторе пользовательского класса A используется метод «LoadParam», который в конечном итоге делает
if (rdr != null)
rdr.Close();
Похоже, что rdr.close () неявно закрывает мое соединение, которое в порядке при использовании автоматического обращения. Но во время транзакции, как правило, не очень хорошая идея, чтобы закрыть связь :-)
Мой вопрос: если это замысловая, или это ошибка в Mysqldatareader.
Решение
Это было сложно! После небольшой отладки я обнаружил следующий метод в файле 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;
}
Довольно тяжелая ошибка, это невозможным запросы в транзакции (я должен признать, что мне никогда не нужно было это раньше).