protected RecalculationReport RecalculateAccount(FilterCriteriaSet filter, Guid processId, string periodAlias, int attemptNumber) { var report = new RecalculationReport(); List <Guid> idsToRecalc = null; var period = Periods.FirstOrDefault(p => p.Alias.Equals(periodAlias, StringComparison.InvariantCultureIgnoreCase)); var accounts = GetAccounts(filter, period); var ids = accounts.Item1.Select(a => (Guid)(a as DynamicEntity).GetId()).ToList(); try { idsToRecalc = ids.Where(id => Locker.TryLock(id, processId)).ToList(); report.NotCalculatedDueToLock.AddRange(ids.Where(id => !idsToRecalc.Contains(id))); var etran = GetCalculationObjects(ids, period, CalculationObjectType.ExternalTransaction); var itran = GetCalculationObjects(ids, period, CalculationObjectType.InternalTransaction); var res = Recalc(accounts, etran, itran); foreach (var resItem in res) { DynamicRepository.UpdateByEntity(resItem.Item1, resItem.Item2); } AfterRecalc(accounts.Item1); } finally { if (idsToRecalc != null) { idsToRecalc.ForEach(id => Locker.Unlock(id, processId)); } } if (attemptNumber < RetryCount && report.NotCalculatedDueToLock.Any()) { Thread.Sleep(LimitLockWaitForRecalc); return(RecalculateAccount(report.NotCalculatedDueToLock, processId, periodAlias, attemptNumber + 1)); } return(report); }
protected RecalculationReport RecalculateAccountByDelta(List<RecalculateRequestDelta> requests, Guid processId, int attemptNumber) { var report = new RecalculationReport(); List<Guid> idsToRecalc = null; var ids = requests.Select(r => r.AccountId).Distinct().ToList(); try { idsToRecalc = ids.Where(id => Locker.TryLock(id, processId)).ToList(); report.NotCalculatedDueToLock.AddRange(ids.Where(id => !idsToRecalc.Contains(id))); var accounts = GetCalculationObjects(idsToRecalc, null, CalculationObjectType.Account); foreach (var idToRecalc in idsToRecalc) { var entity = accounts.Item1.FirstOrDefault( e => (e as DynamicEntity).GetProperty(AccountObject.EntitySearchProperty).Equals(idToRecalc)); if (entity == null) continue; var details = accounts.Item2.Where( e => (e as DynamicEntity).GetProperty(AccountObject.DetailSearchProperty).Equals(idToRecalc)) .ToList(); var recalc = idToRecalc; var selectedRequests = requests.Where(r => r.AccountId.Equals(recalc)).ToList(); if (selectedRequests.Any()) { var res = RecalcByDelta(entity, details, selectedRequests); foreach (var resItem in res) { DynamicRepository.UpdateByEntity(resItem.Item1, resItem.Item2); } AfterRecalc(new List<dynamic> { entity }); } } } finally { if (idsToRecalc != null) idsToRecalc.ForEach(id => Locker.Unlock(id, processId)); } if (attemptNumber < RetryCount) { var notCalculatedRequests = requests.Where(r => !idsToRecalc.Contains(r.AccountId)).ToList(); if (notCalculatedRequests.Any()) { Thread.Sleep(LimitLockWaitForRecalc); return RecalculateAccountByDelta(notCalculatedRequests, processId, attemptNumber + 1); } } return report; }
/// <summary> /// /// </summary> /// <param name="ids"></param> /// <param name="processId"></param> /// <param name="periodAlias"></param> /// <param name="attemptNumber">Номер попытки</param> /// <returns></returns> protected RecalculationReport RecalculateAccount(List<Guid> ids, Guid processId, string periodAlias, int attemptNumber) { var report = new RecalculationReport(); List<Guid> idsToRecalc = null; var period = Periods.FirstOrDefault(p => p.Alias.Equals(periodAlias, StringComparison.InvariantCultureIgnoreCase)); try { idsToRecalc = ids.Where(id => Locker.TryLock(id, processId)).ToList(); report.NotCalculatedDueToLock.AddRange(ids.Where(id => !idsToRecalc.Contains(id))); var accounts = GetCalculationObjects(ids, period, CalculationObjectType.Account); var etran = GetCalculationObjects(ids, period, CalculationObjectType.ExternalTransaction); var itran = GetCalculationObjects(ids, period, CalculationObjectType.InternalTransaction); var res = Recalc(accounts, etran, itran); foreach (var resItem in res) { DynamicRepository.UpdateByEntity(resItem.Item1, resItem.Item2); } AfterRecalc(accounts.Item1); } finally { if (idsToRecalc != null) idsToRecalc.ForEach(id => Locker.Unlock(id, processId)); } if (attemptNumber < RetryCount && report.NotCalculatedDueToLock.Any()) { Thread.Sleep(LimitLockWaitForRecalc); return RecalculateAccount(report.NotCalculatedDueToLock, processId, periodAlias, attemptNumber + 1); } return report; }
protected RecalculationReport RecalculateAccountByDelta(List <RecalculateRequestDelta> requests, Guid processId, int attemptNumber) { var report = new RecalculationReport(); List <Guid> idsToRecalc = null; var ids = requests.Select(r => r.AccountId).Distinct().ToList(); try { idsToRecalc = ids.Where(id => Locker.TryLock(id, processId)).ToList(); report.NotCalculatedDueToLock.AddRange(ids.Where(id => !idsToRecalc.Contains(id))); var accounts = GetCalculationObjects(idsToRecalc, null, CalculationObjectType.Account); foreach (var idToRecalc in idsToRecalc) { var entity = accounts.Item1.FirstOrDefault( e => (e as DynamicEntity).GetProperty(AccountObject.EntitySearchProperty).Equals(idToRecalc)); if (entity == null) { continue; } var details = accounts.Item2.Where( e => (e as DynamicEntity).GetProperty(AccountObject.DetailSearchProperty).Equals(idToRecalc)) .ToList(); var recalc = idToRecalc; var selectedRequests = requests.Where(r => r.AccountId.Equals(recalc)).ToList(); if (selectedRequests.Any()) { var res = RecalcByDelta(entity, details, selectedRequests); foreach (var resItem in res) { DynamicRepository.UpdateByEntity(resItem.Item1, resItem.Item2); } AfterRecalc(new List <dynamic> { entity }); } } } finally { if (idsToRecalc != null) { idsToRecalc.ForEach(id => Locker.Unlock(id, processId)); } } if (attemptNumber < RetryCount) { var notCalculatedRequests = requests.Where(r => !idsToRecalc.Contains(r.AccountId)).ToList(); if (notCalculatedRequests.Any()) { Thread.Sleep(LimitLockWaitForRecalc); return(RecalculateAccountByDelta(notCalculatedRequests, processId, attemptNumber + 1)); } } return(report); }