초기커밋
This commit is contained in:
213
ServerBase/DB/MySqlDb/MySqlDbConnector.cs
Normal file
213
ServerBase/DB/MySqlDb/MySqlDbConnector.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
|
||||
using MySqlConnector;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public partial class MySqlDbConnector : IDisposable
|
||||
{
|
||||
// MySql 접속 재시도 간격 시간 밀리초)
|
||||
private Int32 MYSQL_CONNECT_RETRY_INTERVAL_MSEC = 3000;
|
||||
// MySql 접속 재시도 간격 활성화 조건 실패 횟수
|
||||
private Int32 MYSQL_CONNECT_RETRY_INTERVAL_ENABLE_CONDITION_FAILED_COUNT = 3;
|
||||
// private Int16 m_curr_retry_connect_count = 0;
|
||||
|
||||
private string m_connection_string = string.Empty;
|
||||
|
||||
private MySqlConnection? m_connection;
|
||||
private ConnectionState m_last_connection_state = ConnectionState.Closed;
|
||||
|
||||
private delegate int MyDelegate(int a, int b);
|
||||
|
||||
public MySqlDbConnector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public async Task<ServerErrorCode> initMySql(string connectionString)
|
||||
{
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var error_code = createConnection(connectionString);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
return error_code;
|
||||
}
|
||||
|
||||
error_code = await openMySql();
|
||||
if (error_code.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed to initMySql() !!! : errorCode:{error_code} - connectString:{m_connection_string}");
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public ServerErrorCode createConnection(string connectionString)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(null != m_connection)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
m_connection_string = connectionString;
|
||||
m_connection = new MySqlConnection(connectionString);
|
||||
|
||||
// 연결 상태 변경에 대한 이벤트를 받기 위해 등록 한다. - kangms
|
||||
m_connection.StateChange += new StateChangeEventHandler(onStateChange);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, new MySqlConnection() !!! : message:{e}, connectString:{m_connection_string}");
|
||||
return ServerErrorCode.MySqlConnectionCreateFailed;
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> openMySql()
|
||||
{
|
||||
if (m_connection == null)
|
||||
{
|
||||
return ServerErrorCode.MySqlConnectionCreateFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await m_connection.OpenAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.getLogger().error($"Exception to open MySqlConnection !!! : errDesc:{e.Message} - connectString:{m_connection_string}");
|
||||
return ServerErrorCode.MySqlConnectionOpenFailed;
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// 객체 소멸시점 MySqlConnection 이 ConnectionPool 에 반환될 수 있도록
|
||||
// MySqlConnection.Dispose() 를 반드시 호출해 주어야 한다. - kangms
|
||||
if (m_connection != null)
|
||||
{
|
||||
m_connection.Dispose();
|
||||
m_connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void disposeMySql()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// MySqlDbConnector.onStateChange() 함수가 호출되는 시점은
|
||||
// 1. Self Disconnect : MySqlConnection.Dispose() 이 호출되는 시점 (Using 으로 생성후 Using 범위를 벗어나는 순간, 즉 GC 호출 시점)
|
||||
// 2. Other Disconnect : 실제로 MySql 서버와 끊어진 경우
|
||||
// 3. 기타 : 비정상적인 상황
|
||||
//=========================================================================================
|
||||
private void onStateChange(object sender, StateChangeEventArgs e)
|
||||
{
|
||||
if (m_connection == null)
|
||||
{
|
||||
Log.getLogger().error($"Failed to onStateChange(), Connection is null or CurrentState is null !!! - connectString:{m_connection_string}");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.CurrentState)
|
||||
{
|
||||
case ConnectionState.Closed:
|
||||
Log.getLogger().debug($"Closed MySqlConnector !!! - connectString:{m_connection_string}");
|
||||
break;
|
||||
|
||||
case ConnectionState.Open:
|
||||
Log.getLogger().debug($"Opened MySqlConnector !!! - connectString:{m_connection_string}");
|
||||
break;
|
||||
}
|
||||
|
||||
m_last_connection_state = e.CurrentState;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> retryOpenMySql()
|
||||
{
|
||||
Log.getLogger().info($"Retry db connect start !!! - connectString:{m_connection_string}");
|
||||
|
||||
var error_code = ServerErrorCode.Success;
|
||||
|
||||
for (var i = 0; i < MYSQL_CONNECT_RETRY_INTERVAL_ENABLE_CONDITION_FAILED_COUNT; i++)
|
||||
{
|
||||
await Task.Delay(MYSQL_CONNECT_RETRY_INTERVAL_MSEC);
|
||||
|
||||
error_code = createConnection(m_connection_string);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed to createConnection() when retryOpenMySql() !!! : errorCode:{error_code}, retryCount:{i} - connectString:{m_connection_string}");
|
||||
continue;
|
||||
}
|
||||
|
||||
error_code = await openMySql();
|
||||
if (error_code.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed to openMySql() when retryOpenMySql() !!! : errorCode:{error_code}, retryCount:{i} - connectString:{m_connection_string}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.getLogger().info($"Success Retry db connect !!! : retryCount:{i} - connectString:{m_connection_string}");
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
public async Task<ServerErrorCode> querySQL(string queryString, Func<MySqlDataReader, ServerErrorCode> dataReader)
|
||||
{
|
||||
var error_code = ServerErrorCode.Success;
|
||||
|
||||
try
|
||||
{
|
||||
using (var cmd = new MySqlCommand(queryString, m_connection))
|
||||
using (var reader = await cmd.ExecuteReaderAsync())
|
||||
{
|
||||
if (true == await reader.ReadAsync())
|
||||
{
|
||||
if (null != dataReader)
|
||||
{
|
||||
error_code = dataReader.Invoke(reader);
|
||||
if (error_code.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed to dataReader.Invoke() when querySQL() !!! : errorCode:{error_code}, queryString:{queryString} - connectString:{m_connection_string}");
|
||||
return error_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error_code = ServerErrorCode.MySqlDbQueryException;
|
||||
var err_msg = $"Exception !!!, Failed to query for Read when querySQL() !!! : errorCode:{error_code}, exception:{e}, queryString:{queryString} - connectString:{m_connection_string}";
|
||||
Log.getLogger().fatal(err_msg);
|
||||
return error_code;
|
||||
}
|
||||
|
||||
return error_code;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user