介绍:文件上传功能,使用wcf提供服务,数据库使用EntityFramework4访问。
问题现象:在wcf有一个文件块上传方法
/// <summary>
/// 上传文件
/// </summary>
/// <param name="block">文件块信息</param>
/// <returns>上传文件的信息状态</returns>
public override FileTransportAck UpLoadFile(FileBlock block)
{
lock (lockobj)
{
//查找文件是否存在
tab_FileInfo theFileInfo = m_NetBidEnt.tab_FileInfo
.Where(o => o.FileID.Equals(block.FileID))
.FirstOrDefault();
if (theFileInfo == null)
throw new Exception("文件未初始化,上传失败");
//返回传输结果
FileTransportAck result = new FileTransportAck();
//写入文件块
if (FileSysIO.WriteBlock(theFileInfo, block))
{
theFileInfo.UploadedSize += block.Size;
theFileInfo.FileSize = block.Total;
theFileInfo.UpdateDate = DateTime.Now;
m_NetBidEnt.SaveChanges();
}
else
throw new Exception("写入文件块失败");
//写入返回值
result.FileId = theFileInfo.FileID;
result.Offset = (long)theFileInfo.UploadedSize;
if (theFileInfo.UploadedSize >= block.Total)
result.TransportStat = FileTransportStat.Finished;
else
result.TransportStat = FileTransportStat.ResumeBreakPoint;
return result;
}
}
此方法会在上传文件时循环调用,基本是每10K传一次,即会调用此访问一次,但很奇怪的问题是如果文件在10M以上时,传输过程中会出现停止。。此时查看数据库服务整体就像是锁死了一样,使用ssms也无法连接,报出的异常都是连接超时。
后来在wcf的方法内增加了日志用于记录异常,记录的异常如下:
Exception Message
2011-07-28 00:38:26,451 An error occurred while starting a transaction on the provider connection. See the inner exception for details.
StackTrace
2011-07-28 00:38:26,467 at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Objects.ObjectContext.SaveChanges()
at NetBid.FileServices.Impl.FileSysFileService.UpLoadFile(FileBlock block)
at NetBid.FileServices.Wcf.FileServiceWCF.UploadFileBlock(FileBlock block, Dictionary`2 parameters)
Inner Exception:
2011-07-28 00:38:26,467 Inner Exception:System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
at System.Data.SqlClient.TdsParserStateObject.ReadByte()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlInternalConnection.BeginTransaction(IsolationLevel iso)
at System.Data.SqlClient.SqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.Common.DbConnection.BeginTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
2011-07-28 00:38:26,467 =======================================================分割线
异常看上去像是事务问题,但有一个奇怪的现象是:上传过程中一旦出现停止现象后,整个数据库都无法访问,只能将数据库的服务停止并重新启动。
上传本身和数据库有啥关系?你的web服务器和数据库服务器是一台机器?
不知道你的DB访问代码是怎么写的,从现在的现象看应该是已经达到最大连接数了。所以连接不上,超时了。
是不是每次操作完没关闭连接啊。