private void AddError(int index, string indexName, string key, string error, string component) { var increment = Interlocked.Increment(ref errorsCounter); var indexingError = new IndexingError { Id = increment, Document = key, Error = error, Index = index, IndexName = indexName, Action = component, Timestamp = SystemTime.UtcNow }; indexingErrors.Enqueue(indexingError); IndexingError ignored = null; lock (indexingErrorLocks.GetOrAdd(index, new object())) { using (TransactionalStorage.DisableBatchNesting()) TransactionalStorage.Batch(accessor => { accessor.Lists.Set("Raven/Indexing/Errors/" + indexName, indexingError.Id.ToString(CultureInfo.InvariantCulture), RavenJObject.FromObject(indexingError), UuidType.Indexing); if (indexingErrors.Count <= 50) return; if (indexingErrors.TryDequeue(out ignored) == false) return; if (index != ignored.Index || (SystemTime.UtcNow - ignored.Timestamp).TotalSeconds <= 10) return; accessor.Lists.RemoveAllOlderThan("Raven/Indexing/Errors/" + ignored.IndexName, ignored.Timestamp); }); } if (ignored == null || index == ignored.Index) return; if ((SystemTime.UtcNow - ignored.Timestamp).TotalSeconds <= 10) return; lock (indexingErrorLocks.GetOrAdd(ignored.Index, new object())) { using (TransactionalStorage.DisableBatchNesting()) TransactionalStorage.Batch(accessor => { accessor.Lists.RemoveAllOlderThan("Raven/Indexing/Errors/" + ignored.IndexName, ignored.Timestamp); }); } }
public override void Commit(string id) { EsentTransactionContext context; if (transactionContexts.TryGetValue(id, out context) == false) { throw new InvalidOperationException("There is no transaction with id: " + id + " ready to commit. Did you call PrepareTransaction?"); } lock (context) { //using(context.Session) - disposing the session is actually done in the rollback, which is always called using (context.EnterSessionContext()) { context.Transaction.Commit(txMode); if (context.DocumentIdsToTouch != null) { using (docDb.DocumentLock.Lock()) { using (storage.DisableBatchNesting()) { storage.Batch(accessor => { foreach (var docId in context.DocumentIdsToTouch) { docDb.CheckReferenceBecauseOfDocumentUpdate(docId, accessor); try { Etag preTouchEtag; Etag afterTouchEtag; accessor.Documents.TouchDocument(docId, out preTouchEtag, out afterTouchEtag); } catch (ConcurrencyException) { log.Info("Concurrency exception when touching {0}", docId); } } }); } } } foreach (var afterCommit in context.ActionsAfterCommit) { afterCommit(); } } } }
public void ClearErrorsFor(string indexName) { var list = new List <IndexingError>(); var removed = new List <IndexingError>(); IndexingError error; while (indexingErrors.TryDequeue(out error)) { if (StringComparer.OrdinalIgnoreCase.Equals(error.IndexName, indexName) == false) { list.Add(error); } else { removed.Add(error); } } foreach (var indexingError in list) { indexingErrors.Enqueue(indexingError); } var removedIndexIds = removed .Select(x => x.Index) .Distinct(); foreach (var removedIndexId in removedIndexIds) { object _; indexingErrorLocks.TryRemove(removedIndexId, out _); } TransactionalStorage.Batch(accessor => { foreach (var removedError in removed) { accessor.Lists.Remove("Raven/Indexing/Errors/" + indexName, removedError.Id.ToString(CultureInfo.InvariantCulture)); } using (TransactionalStorage.DisableBatchNesting()) accessor.Lists.RemoveAllOlderThan("Raven/Indexing/Errors/" + indexName, DateTime.MaxValue); }); }