对象和多线程问题
本文关键字:问题 多线程 对象 | 更新日期: 2023-09-27 17:51:20
我们使用实体框架4作为我们的web应用程序和Ninject作为我们的DI容器。我们有一个日志表来记录我们应用程序中发生的所有事情,我们也有后台WCF工作流服务,它再次将日志写入日志表。
对于所有来自web的请求,我们使用
StandardScopeCallbacks.Request(ctx);
后端使用
StandardScopeCallbacks.ThreadScope(ctx);
我们的日志方法非常简单
public void Log(string message, LogLevel level)
{
var log = new ApplicationLog()
{
LogDate = DateTime.Now,
Message = message,
LogLevel = Enum.GetName(typeof(LogLevel), level)
};
db.ApplicationLog.Add(log);
db.SaveChanges();
}
问题:如果我们有更多的线程在运行,那么我们会得到一个异常
System.Data.SqlClient。不允许新建事务因为还有其他线程在会话中运行。在
System.Data.SqlClient.SqlConnection。OnError (SqlException异常,布尔值breakConnection) atSystem.Data.SqlClient.TdsParser.ThrowExceptionAndWarning ()System.Data.SqlClient.TdsParser。运行(RunBehavior RunBehavior,SqlCommand cmdHandler, SqlDataReader dataStreamBulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObjectstateObj)System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (Byte []缓冲区,TransactionManagerRequestType请求,字符串transactionNameTransactionManagerIsolationLevel, Int32超时,SqlInternalTransaction事务,TdsParserStateObject在
System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (TransactionRequesttransactionName, transactionName, IsolationLevelSqlInternalTransaction internalTransaction, BooleanisDelegateControlRequest) at
System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction (IsolationLevel. iso,字符串transactionName)System.Data.SqlClient.SqlInternalConnection.BeginTransaction (IsolationLeveliso)System.Data.SqlClient.SqlConnection.BeginDbTransaction (IsolationLevelisolationLevel)System.Data.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevelisolationLevel)
我知道我可以使用"using"语句创建新的上下文并写入日志表而没有任何问题。但是我不想这样做,因为这会使一切都比在threadscope中创建Context慢。
处理这种情况的最好方法是什么?我需要一个执行时间最少的实现。
如果你需要更多的信息,请留下评论。
你应该听听Daniel的评论。NLog和Log4Net是更好的选择。
我不建议像Jalalx提到的那样锁定db,因为如果你有很多日志,它最终会减慢锁的执行速度。如果你没有大量的日志要写,那么一定要试一试。
两个选项,
- 为每个线程注册数据库连接/上下文,这样你就不必担心跨线程共享,它不会发生。
- 创建一个"DbConnectionFactory"来创建数据库连接/上下文,你可以在每个线程/执行的上下文中调用。
基本上它要么让Ninject管理它,要么创建一个抽象让你可以自己管理它
顺便说一句,ninject不是最慢的。net DI框架吗?