C # с MySQL через Connector / NET - PullRequest
       2

C # с MySQL через Connector / NET

5 голосов
/ 18 марта 2012

Я разрабатываю приложение CMS на C # (4.0 Framework), которое подключается к базе данных MySQL (5.0.95) на удаленном сервере с помощью MySQL, Connector (6.5.4).

У меня проблема с выполнением запросов.

например, Моя строка подключения:

"Server=" + Options.DbServer + ";Database="+ Options.Database +";Uid=" + Options.DbUser + ";Pwd=" + Options.DbPassword + ";CharSet=utf8; Connect Timeout=30;";

У меня есть статический класс, который управляет вещами, связанными с базой данных, и там у меня есть закрытый член _connection.

private static MySqlConnection _connection;
public static MySqlConnection Connection
{ 
    get
    {
        if (_connection.State != ConnectionState.Open)
            _connection.Open();

        return _connection;
    } 
    set { _connection = value; }
}

Это методкоторый инициализирует соединение:

public static bool Init(string cs)
{
    _connection = new MySqlConnection(cs);
    MySqlCommand command = new MySqlCommand("SET NAMES utf8", Connection);
    command.ExecuteNonQuery();
    return true;
}

Это метод, в котором я получаю исключение:

public static bool InsertRecord(MySqlCommand command)
{
    command.Connection = Connection;
    if(command.ExecuteNonQuery() > 0)
        return true;

    return false;
}

command.ExecuteNonQuery() выдает исключение: произошла фатальная ошибка при выполнении команды.

Thisтакое трассировка стека ...

MySql.Data.MySqlClient.MySqlException was unhandled
  Message=Fatal error encountered during command execution.
  Source=MySql.Data
  ErrorCode=-2147467259
  Number=0
  StackTrace:
       at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
       at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
       at CMS.Database.InsertRecord(MySqlCommand command) in C:\_myStuff\VS2010\CMS\CMS\Database.cs:line 95
       at CMS.frmAddItem.btnDo_Click(Object sender, EventArgs e) in C:\_myStuff\VS2010\CMS\CMS\frmAddItem.cs:line 138
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.RunDialog(Form form)
       at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       at System.Windows.Forms.Form.ShowDialog()
       at CMS.frmMain.btnNovi_Click(Object sender, EventArgs e) in C:\_myStuff\VS2010\CMS\CMS\frmMain.cs:line 381
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.RunDialog(Form form)
       at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       at System.Windows.Forms.Form.ShowDialog()
       at CMS.frmLogin.DoLogin() in C:\_myStuff\VS2010\CMS\CMS\frmLogin.cs:line 55
       at CMS.frmLogin.button2_Click(Object sender, EventArgs e) in C:\_myStuff\VS2010\CMS\CMS\frmLogin.cs:line 31
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at CMS.Program.Main() in C:\_myStuff\VS2010\CMS\CMS\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: MySql.Data.MySqlClient.MySqlException
       Message=Fatal error encountered attempting to read the resultset.
       Source=MySql.Data
       ErrorCode=-2147467259
       Number=0
       StackTrace:
            at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
            at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
       InnerException: MySql.Data.MySqlClient.MySqlException
            Message=Reading from the stream has failed.
            Source=MySql.Data
            ErrorCode=-2147467259
            Number=0
            StackTrace:
                 at MySql.Data.MySqlClient.MySqlStream.LoadPacket()
                 at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
                 at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& insertedId)
                 at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int32& insertedId)
                 at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
                 at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
            InnerException: System.IO.EndOfStreamException
                 Message=Attempted to read past the end of the stream.
                 Source=MySql.Data
                 StackTrace:
                      at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte[] buffer, Int32 offset, Int32 count)
                      at MySql.Data.MySqlClient.MySqlStream.LoadPacket()
                 InnerException:

Есть предложения?

Ответы [ 4 ]

6 голосов
/ 19 марта 2012

Я замечаю, что вы открываете соединения, но не закрываете их, когда закончите с ними.Я предпочитаю подход открытия связей, когда они необходимы, а не открытия их, если они еще не открыты.Они могут быть устаревшими.

Кэшировать строку соединения , но не само соединение.

public static string ConnectionString {get;set;}

public static bool InsertRecord(sql)
{
    bool success = false;
    using (var con = new Connection(ConnectionString)){
        var command = new SqlCommand(sql,con);
        success = (command.ExecuteNonQuery() > 0);
    }
    return success;
}

Ресурсы должны быть освобождены, когда они больше не нужны.

3 голосов
/ 18 марта 2012

Я предлагаю вам проверить этот отчет об ошибке по этой проблеме.

1 голос
/ 19 марта 2012

MySQL использует кучу разных переменных времени ожидания на разных уровнях.

Когда устанавливается соединение -> connect_timeout

Когда сервер ожидает в режиме ожидания для отправки другого запроса -> wait_timeout

Если запрос читается или набор результатов отправляется обратно -> net_read_timeout и net_write_timeout

И net_write_timeout, и net_read_timeout являются переменными уровня сеанса, поэтому вы можете просто изменитьих на соединения, когда вы знаете, что запрос будет проблематичным и, следовательно, он не повлияет на остальную часть сервера.(в качестве обходного пути)

Но сначала вы должны проверить значение по умолчанию для каждого из этих значений времени ожидания на вашем сервере, выполнив что-то вроде:

show variables like '%timeout%'

Вы также должны посмотреть на командуВы вставляете и посмотрите, может ли это быть упрощено или разбито на небольшие обновления.

0 голосов
/ 10 мая 2018

Добавление MySqlDataAdapter.SelectCommand.CommandTimeout = 600 сработало для меня.Вот ссылка, где я ее нашел:

https://www.codeproject.com/Questions/665556/Connection-Timeout-Problem-with-MySqlDataAdapter-h

...