mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-12-24 01:25:48 +08:00
- 调整 Aop 改为 event 事件;
- 调整 Ado.AopCommandExecuting/AopCommandExecuted 到 Aop.CommandBefore/After; - 增加 Aop.TraceBefore/After 事件;
This commit is contained in:
@@ -17,10 +17,8 @@ namespace FreeSql.Internal.CommonProvider
|
||||
protected abstract void ReturnConnection(IObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex);
|
||||
protected abstract DbCommand CreateCommand();
|
||||
protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
|
||||
public Action<DbCommand> AopCommandExecuting { get; set; }
|
||||
public Action<DbCommand, string> AopCommandExecuted { get; set; }
|
||||
|
||||
protected bool IsTracePerformance => AopCommandExecuted != null;
|
||||
protected bool IsTracePerformance => _util?._orm?.Aop.CommandAfterHandler != null;
|
||||
|
||||
public IObjectPool<DbConnection> MasterPool { get; protected set; }
|
||||
public List<IObjectPool<DbConnection>> SlavePools { get; } = new List<IObjectPool<DbConnection>>();
|
||||
@@ -35,22 +33,22 @@ namespace FreeSql.Internal.CommonProvider
|
||||
this.DataType = dataType;
|
||||
}
|
||||
|
||||
void LoggerException(IObjectPool<DbConnection> pool, (DbCommand cmd, bool isclose) pc, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true)
|
||||
void LoggerException(IObjectPool<DbConnection> pool, (Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) pc, Exception ex, DateTime dt, StringBuilder logtxt, bool isThrowException = true)
|
||||
{
|
||||
var cmd = pc.cmd;
|
||||
if (pc.isclose) pc.cmd.Connection.Close();
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
TimeSpan ts = DateTime.Now.Subtract(dt);
|
||||
if (e == null && ts.TotalMilliseconds > 100)
|
||||
if (ex == null && ts.TotalMilliseconds > 100)
|
||||
Trace.WriteLine(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString());
|
||||
else
|
||||
logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString();
|
||||
}
|
||||
|
||||
if (e == null)
|
||||
if (ex == null)
|
||||
{
|
||||
AopCommandExecuted?.Invoke(cmd, logtxt.ToString());
|
||||
_util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +57,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
foreach (DbParameter parm in cmd.Parameters)
|
||||
log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n");
|
||||
|
||||
log.Append(e.Message);
|
||||
log.Append(ex.Message);
|
||||
Trace.WriteLine(log.ToString());
|
||||
|
||||
if (cmd.Transaction != null)
|
||||
@@ -70,16 +68,16 @@ namespace FreeSql.Internal.CommonProvider
|
||||
//cmd.Transaction.Rollback();
|
||||
}
|
||||
else
|
||||
RollbackTransaction();
|
||||
RollbackTransaction(ex);
|
||||
}
|
||||
|
||||
AopCommandExecuted?.Invoke(cmd, log.ToString());
|
||||
_util?._orm?.Aop.CommandAfterHandler?.Invoke(_util._orm, new Aop.CommandAfterEventArgs(pc.before, null, logtxt.ToString()));
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
if (isThrowException)
|
||||
{
|
||||
if (DataType == DataType.Sqlite) cmd.Dispose();
|
||||
throw e;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,11 +545,14 @@ namespace FreeSql.Internal.CommonProvider
|
||||
|
||||
Object<DbConnection> conn = null;
|
||||
var pc = PrepareCommand(connection, transaction, cmdType, cmdText, cmdParms, logtxt);
|
||||
if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
Exception ex = null;
|
||||
try
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
if (isSlave)
|
||||
{
|
||||
//从库查询切换,恢复
|
||||
@@ -571,7 +572,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -587,43 +588,31 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt.Append("Pool.Get: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
using (var dr = pc.cmd.ExecuteReader())
|
||||
{
|
||||
if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
int resultIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
bool isread = dr.Read();
|
||||
if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (isread == false) break;
|
||||
|
||||
if (readerHander != null)
|
||||
{
|
||||
object[] values = null;
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt_dt = DateTime.Now;
|
||||
values = new object[dr.FieldCount];
|
||||
dr.GetValues(values);
|
||||
logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
readerHander(dr, resultIndex);
|
||||
if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
|
||||
}
|
||||
}
|
||||
if (++resultIndex >= multipleResult || dr.NextResult() == false) break;
|
||||
}
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
dr.Close();
|
||||
}
|
||||
if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
@@ -632,9 +621,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
|
||||
if (conn != null)
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
LoggerException(pool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -735,7 +727,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -771,7 +763,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -779,7 +771,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
return val;
|
||||
}
|
||||
|
||||
(DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt)
|
||||
(Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose) PrepareCommand(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt)
|
||||
{
|
||||
var dt = DateTime.Now;
|
||||
DbCommand cmd = CreateCommand();
|
||||
@@ -800,14 +792,10 @@ namespace FreeSql.Internal.CommonProvider
|
||||
if (connection == null)
|
||||
{
|
||||
var tran = transaction ?? TransactionCurrentThread;
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
|
||||
|
||||
if (tran != null && connection == null)
|
||||
{
|
||||
if (IsTracePerformance) dt = DateTime.Now;
|
||||
cmd.Connection = tran.Connection;
|
||||
cmd.Transaction = tran;
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -825,11 +813,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
|
||||
if (IsTracePerformance) dt = DateTime.Now;
|
||||
AutoCommitTransaction();
|
||||
if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
CommitTimeoutTransaction();
|
||||
if (IsTracePerformance) logtxt.Append(" CommitTimeoutTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
|
||||
AopCommandExecuting?.Invoke(cmd);
|
||||
return (cmd, isclose);
|
||||
var before = new Aop.CommandBeforeEventArgs(cmd);
|
||||
_util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before);
|
||||
return (before, cmd, isclose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,11 +476,14 @@ namespace FreeSql.Internal.CommonProvider
|
||||
|
||||
Object<DbConnection> conn = null;
|
||||
var pc = await PrepareCommandAsync(connection, transaction, cmdType, cmdText, cmdParms, logtxt);
|
||||
if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
Exception ex = null;
|
||||
try
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
if (isSlave)
|
||||
{
|
||||
//从库查询切换,恢复
|
||||
@@ -500,7 +503,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(pool, pc, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -516,43 +519,31 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt.Append("Pool.Get: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
using (var dr = await pc.cmd.ExecuteReaderAsync())
|
||||
{
|
||||
if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
int resultIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
bool isread = await dr.ReadAsync();
|
||||
if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (isread == false) break;
|
||||
|
||||
if (readerHander != null)
|
||||
{
|
||||
object[] values = null;
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt_dt = DateTime.Now;
|
||||
values = new object[dr.FieldCount];
|
||||
for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
|
||||
logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
await readerHander(dr, resultIndex);
|
||||
if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
|
||||
}
|
||||
}
|
||||
if (++resultIndex >= multipleResult || dr.NextResult() == false) break;
|
||||
}
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
dr.Close();
|
||||
}
|
||||
if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (IsTracePerformance)
|
||||
{
|
||||
logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
logtxt_dt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
@@ -563,7 +554,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(pool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -665,7 +656,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -701,7 +692,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
if (IsTracePerformance) logtxt.Append("Pool.Return: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||
}
|
||||
LoggerException(this.MasterPool, pc, ex, dt, logtxt);
|
||||
pc.cmd.Parameters.Clear();
|
||||
@@ -709,7 +700,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
return val;
|
||||
}
|
||||
|
||||
async Task<(DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt)
|
||||
async Task<(Aop.CommandBeforeEventArgs before, DbCommand cmd, bool isclose)> PrepareCommandAsync(DbConnection connection, DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt)
|
||||
{
|
||||
DateTime dt = DateTime.Now;
|
||||
DbCommand cmd = CreateCommand();
|
||||
@@ -733,10 +724,8 @@ namespace FreeSql.Internal.CommonProvider
|
||||
|
||||
if (tran != null)
|
||||
{
|
||||
if (IsTracePerformance) dt = DateTime.Now;
|
||||
cmd.Connection = tran.Connection;
|
||||
cmd.Transaction = tran;
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -745,7 +734,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
{
|
||||
if (IsTracePerformance) dt = DateTime.Now;
|
||||
await connection.OpenAsync();
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpenAsync: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommand_ConnectionOpen: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||
isclose = true;
|
||||
}
|
||||
cmd.Connection = connection;
|
||||
@@ -753,10 +742,9 @@ namespace FreeSql.Internal.CommonProvider
|
||||
cmd.Transaction = transaction;
|
||||
}
|
||||
|
||||
if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
|
||||
|
||||
AopCommandExecuting?.Invoke(cmd);
|
||||
return (cmd, isclose);
|
||||
var before = new Aop.CommandBeforeEventArgs(cmd);
|
||||
_util?._orm?.Aop.CommandBeforeHandler?.Invoke(_util._orm, before);
|
||||
return (before, cmd, isclose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
|
||||
class Transaction2
|
||||
{
|
||||
internal Aop.TraceBeforeEventArgs AopBefore;
|
||||
internal Object<DbConnection> Conn;
|
||||
internal DbTransaction Transaction;
|
||||
internal DateTime RunTime;
|
||||
@@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
private object _trans_lock = new object();
|
||||
|
||||
public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null;
|
||||
public Aop.TraceBeforeEventArgs TransactionCurrentThreadAopBefore => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.AopBefore : null;
|
||||
|
||||
public void BeginTransaction(TimeSpan timeout, IsolationLevel? isolationLevel)
|
||||
{
|
||||
@@ -41,16 +43,21 @@ namespace FreeSql.Internal.CommonProvider
|
||||
int tid = Thread.CurrentThread.ManagedThreadId;
|
||||
Transaction2 tran = null;
|
||||
Object<DbConnection> conn = null;
|
||||
var before = new Aop.TraceBeforeEventArgs("ThreadTransaction", isolationLevel);
|
||||
_util?._orm?.Aop.TraceBeforeHandler?.Invoke(this, before);
|
||||
|
||||
try
|
||||
{
|
||||
conn = MasterPool.Get();
|
||||
tran = new Transaction2(conn, isolationLevel == null ? conn.Value.BeginTransaction() : conn.Value.BeginTransaction(isolationLevel.Value), timeout);
|
||||
tran.AopBefore = before;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}");
|
||||
MasterPool.Return(conn);
|
||||
var after = new Aop.TraceAfterEventArgs(before, "", ex);
|
||||
_util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after);
|
||||
throw ex;
|
||||
}
|
||||
if (_trans.ContainsKey(tid)) CommitTransaction();
|
||||
@@ -59,17 +66,17 @@ namespace FreeSql.Internal.CommonProvider
|
||||
_trans.TryAdd(tid, tran);
|
||||
}
|
||||
|
||||
private void AutoCommitTransaction()
|
||||
private void CommitTimeoutTransaction()
|
||||
{
|
||||
if (_trans.Count > 0)
|
||||
{
|
||||
Transaction2[] trans = null;
|
||||
lock (_trans_lock)
|
||||
trans = _trans.Values.Where(st2 => DateTime.Now.Subtract(st2.RunTime) > st2.Timeout).ToArray();
|
||||
foreach (Transaction2 tran in trans) CommitTransaction(true, tran);
|
||||
foreach (Transaction2 tran in trans) CommitTransaction(true, tran, null, "Timeout自动提交");
|
||||
}
|
||||
}
|
||||
private void CommitTransaction(bool isCommit, Transaction2 tran)
|
||||
private void CommitTransaction(bool isCommit, Transaction2 tran, Exception rollbackException, string remark = null)
|
||||
{
|
||||
if (tran == null || tran.Transaction == null || tran.Transaction.Connection == null) return;
|
||||
|
||||
@@ -79,29 +86,34 @@ namespace FreeSql.Internal.CommonProvider
|
||||
_trans.TryRemove(tran.Conn.LastGetThreadId, out var oldtran);
|
||||
|
||||
Exception ex = null;
|
||||
var f001 = isCommit ? "提交" : "回滚";
|
||||
if (string.IsNullOrEmpty(remark)) remark = isCommit ? "提交" : "回滚";
|
||||
try
|
||||
{
|
||||
Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{f001}");
|
||||
Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{remark}");
|
||||
if (isCommit) tran.Transaction.Commit();
|
||||
else tran.Transaction.Rollback();
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
ex = ex2;
|
||||
Trace.WriteLine($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}");
|
||||
Trace.WriteLine($"数据库出错({remark}事务):{ex.Message} {ex.StackTrace}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex);
|
||||
|
||||
var after = new Aop.TraceAfterEventArgs(tran.AopBefore, remark, ex ?? rollbackException);
|
||||
_util?._orm?.Aop.TraceAfterHandler?.Invoke(this, after);
|
||||
}
|
||||
}
|
||||
private void CommitTransaction(bool isCommit)
|
||||
public void CommitTransaction()
|
||||
{
|
||||
if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(isCommit, tran);
|
||||
if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(true, tran, null);
|
||||
}
|
||||
public void RollbackTransaction(Exception ex)
|
||||
{
|
||||
if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(false, tran, ex);
|
||||
}
|
||||
public void CommitTransaction() => CommitTransaction(true);
|
||||
public void RollbackTransaction() => CommitTransaction(false);
|
||||
|
||||
public void Transaction(Action handler) => TransactionInternal(null, TimeSpan.FromSeconds(60), handler);
|
||||
public void Transaction(TimeSpan timeout, Action handler) => TransactionInternal(null, timeout, handler);
|
||||
@@ -117,7 +129,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RollbackTransaction();
|
||||
RollbackTransaction(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -132,7 +144,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
Transaction2[] trans = null;
|
||||
lock (_trans_lock)
|
||||
trans = _trans.Values.ToArray();
|
||||
foreach (Transaction2 tran in trans) CommitTransaction(false, tran);
|
||||
foreach (Transaction2 tran in trans) CommitTransaction(false, tran, null, "Dispose自动提交");
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user