Group: Forum Members
Posts: 190,
Visits: 1.3K
|
Hi I think I found the problem. I fixed it, and tested with stress test, working fine till this moment. Just to share if anyone face the same issue Root Cause: This class is initialized only once per data source. It is initialized and stored in static field. Therefore, it need to support thread-Safe. Under UpdateRow() method, objects _CachedInsertCommands, _CachedUpdateeCommands and _CachedDeleteCommands are designed to support thread-safe by using SyncLock statement. At EndUpdateCommandCaching() method, it will remove some elements from objects as mentioned. However, it is not written with thread-safe support. Symptom: Only happen under stress test, frequent of reproduced not consistent. Suggested Solutions: Class : SqlDataSourceItem.cs Public Overrides Sub EndUpdateCommandCaching(ByVal UpdatingTable As System.Data.DataTable, ByVal Transactional As Boolean) '-- Establish locals Dim loCommand As SqlCommand SyncLock Me._CachedDeleteCommands '-- Clear out the dictionary entries If Me._CachedDeleteCommands.ContainsKey(UpdatingTable) Then '-- Close the connection on the command loCommand = Me._CachedDeleteCommands(UpdatingTable) '-- Make sure that we were not on a transaction If (Not Transactional) AndAlso (loCommand.Connection IsNot Nothing) Then loCommand.Connection.Close() loCommand.Connection.Dispose() End If loCommand.Dispose() '-- Remove it from the dictionary Me._CachedDeleteCommands.Remove(UpdatingTable) End If End SyncLock SyncLock Me._CachedInsertCommands If Me._CachedInsertCommands.ContainsKey(UpdatingTable) Then '-- Close the connection on the command loCommand = Me._CachedInsertCommands(UpdatingTable) '-- Make sure that we were not on a transaction If (Not Transactional) AndAlso (loCommand.Connection IsNot Nothing) Then loCommand.Connection.Close() loCommand.Connection.Dispose() End If loCommand.Dispose() '-- Remove it from the dictionary Me._CachedInsertCommands.Remove(UpdatingTable) End If End SyncLock SyncLock Me._CachedUpdateCommands If Me._CachedUpdateCommands.ContainsKey(UpdatingTable) Then '-- Close the connection on the command loCommand = Me._CachedUpdateCommands(UpdatingTable) '-- Make sure that we were not on a transaction If (Not Transactional) AndAlso (loCommand.Connection IsNot Nothing) Then loCommand.Connection.Close() loCommand.Connection.Dispose() End If loCommand.Dispose() '-- Remove it from the dictionary Me._CachedUpdateCommands.Remove(UpdatingTable) |
Group: Forum Members
Posts: 190,
Visits: 1.3K
|
Hi I tried to put debug code and found that the error happen at SqlDataSourceItem.UpdateRow() at line Me._CachedInsertCommands.Add(RowToUpdate.Table, loCommand) Please advice.
|
Group: Forum Members
Posts: 190,
Visits: 1.3K
|
Hi I have code as below public virtual void Write(string userName, DateTime dated, string objectName, string action, string hostName) { using (ActivityLogsBO logger = new ActivityLogsBO()) { //logger.DataSourceKey = this._dataSource; logger.Write(userName, dated, objectName, action, hostName); } } //--AcitivityBO.cs public void Write(string userName, DateTime logDate, string objectName, string action, string hostName) { this.NewRow(); this.Username = userName; this.DateTime = logDate; this.ObjectName = objectName; this.Action = action; this.HostName = hostName; SaveUndoResult result = this.Save(); if (result != SaveUndoResult.Success) { throw new ApplicationException("Failed to activity log error:" + userName + action); } } When I run stress test to it about 30 vusers, it will hit error as below Exception information: Exception type: DataLayerSavingException Exception message: Index was outside the bounds of the array. Request information: Request URL: http://kkchan-pc/flexhr_6244/Security/Forms/UserLogin.aspx Request path: /flexhr_6244/Security/Forms/UserLogin.aspx User host address: 192.168.2.100 User: Is authenticated: False Authentication Type: Thread account name: IIS APPPOOL\FlexHR_6244AppPool Thread information: Thread ID: 21 Thread account name: IIS APPPOOL\FlexHR_6244AppPool Is impersonating: False Stack trace: at MicroFour.StrataFrame.Data.DataLayer.UpdateDataTable(DataTable TableToUpdate, Boolean Transactional, String TransactionKey) at MicroFour.StrataFrame.Data.DataLayer.Save(DataTable TableToSave, Boolean Transactional, String TransactionKey) at MicroFour.StrataFrame.Business.BusinessLayer.Save(Boolean Transactional, String TransactionKey) at MicroFour.StrataFrame.Business.BusinessLayer.Save() at Vfs.Security.Common.ActiveUserController.Register(String SessionId, ISecurityUserEx CurrentUser) at Vfs.Security.Common.Extensions.LoggedInUserEx.SetLoggedOnUser(SFSUsersBO UserInfo, String ClientIP) at Vfs.Security.Common.SFSecurityBasics.SetLoggedOnUser(SFSUsersBO Users, String ClientIP) at Vfs.Security.UI.Web.LoginController.AttempLogin(String userName, String password, String domainName) in D:\FlexHR\Branches\6.2.0\Security\UI\Web\Controllers\LoginController.cs:line 659 at Vfs.Security.UI.Web.Controls.LoginContainer.AuthenticateLogin() in D:\FlexHR\Branches\6.2.0\Security\UI\Web\Controls\LoginContainer.cs:line 243 at Vfs.Security.UI.Web.Controls.LoginContainer.LoginButton_Click(Object sender, EventArgs e) in D:\FlexHR\Branches\6.2.0\Security\UI\Web\Controls\LoginContainer.cs:line 236 at System.EventHandler.Invoke(Object sender, EventArgs e) at DevExpress.Web.ASPxEditors.ASPxButton.OnClick(EventArgs e) at DevExpress.Web.ASPxEditors.ASPxButton.RaisePostBackEvent(String eventArgument) at DevExpress.Web.ASPxClasses.ASPxWebControl.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) Any ideas? Please advice.
|