Ejemplo n.º 1
0
        public void PulseTransaction()
        {
            try
            {
                storageActionsAccessor.ExecuteBeforeStorageCommit();

                storage.Write(writeBatch.Value);

                writeBatch.Value.Dispose();

                var hasOpenedIterators = snapshot.Value.HasOpenedIterators;

                snapshot.Value.Dispose();
                if (hasOpenedIterators)
                {
                    throw new InvalidOperationException("Cannot pulse transaction when we have iterators opened");
                }

                snapshot.Value = storage.CreateSnapshot();

                writeBatch.Value = new WriteBatch {
                    DisposeAfterWrite = writeBatch.Value.DisposeAfterWrite
                };
            }
            finally
            {
                storageActionsAccessor.ExecuteAfterStorageCommit();
            }
        }
Ejemplo n.º 2
0
        private void ExecuteBatch(Action <IStorageActionsAccessor> action)
        {
            var snapshotRef   = new Reference <SnapshotReader>();
            var writeBatchRef = new Reference <WriteBatch>();

            try
            {
                snapshotRef.Value   = tableStorage.CreateSnapshot();
                writeBatchRef.Value = new WriteBatch {
                    DisposeAfterWrite = false
                };                                                                  // prevent from disposing after write to allow read from batch OnStorageCommit
                var storageActionsAccessor = new StorageActionsAccessor(tableStorage, writeBatchRef, snapshotRef, idGenerator, bufferPool, uuidGenerator, fileCodecs);
                if (disableBatchNesting.Value == null)
                {
                    current.Value = storageActionsAccessor;
                }

                action(storageActionsAccessor);
                storageActionsAccessor.Commit();

                tableStorage.Write(writeBatchRef.Value);
            }
            finally
            {
                if (snapshotRef.Value != null)
                {
                    snapshotRef.Value.Dispose();
                }

                if (writeBatchRef.Value != null)
                {
                    writeBatchRef.Value.Dispose();
                }
            }
        }
Ejemplo n.º 3
0
        private void ExecuteBatch(Action <IStorageActionsAccessor> action)
        {
            if (current.Value != null)
            {
                action(current.Value);
                return;
            }

            using (var snapshot = tableStorage.CreateSnapshot())
            {
                var writeBatchRef = new Reference <WriteBatch>();
                try
                {
                    writeBatchRef.Value = new WriteBatch {
                        DisposeAfterWrite = false
                    };
                    using (var storageActionsAccessor = new StorageActionsAccessor(tableStorage, writeBatchRef, snapshot, idGenerator, bufferPool))
                    {
                        current.Value = storageActionsAccessor;

                        action(storageActionsAccessor);
                        storageActionsAccessor.Commit();

                        tableStorage.Write(writeBatchRef.Value);
                    }
                }
                finally
                {
                    if (writeBatchRef.Value != null)
                    {
                        writeBatchRef.Value.Dispose();
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void PulseTransaction()
        {
            storage.Write(writeBatch.Value);

            snapshot.Value.Dispose();
            writeBatch.Value.Dispose();

            snapshot.Value   = storage.CreateSnapshot();
            writeBatch.Value = new WriteBatch {
                DisposeAfterWrite = writeBatch.Value.DisposeAfterWrite
            };
        }
Ejemplo n.º 5
0
        public IStorageActionsAccessor CreateAccessor()
        {
            var snapshotReference = new Reference <SnapshotReader> {
                Value = tableStorage.CreateSnapshot()
            };
            var writeBatchReference = new Reference <WriteBatch> {
                Value = new WriteBatch()
            };

            var accessor = new StorageActionsAccessor(uuidGenerator, _documentCodecs,
                                                      documentCacher, writeBatchReference, snapshotReference, tableStorage, this, bufferPool);

            accessor.OnDispose += () =>
            {
                var exceptionAggregator = new ExceptionAggregator("Could not properly dispose StorageActionsAccessor");

                exceptionAggregator.Execute(() => snapshotReference.Value.Dispose());
                exceptionAggregator.Execute(() => writeBatchReference.Value.Dispose());

                exceptionAggregator.ThrowIfNeeded();
            };

            return(accessor);
        }
Ejemplo n.º 6
0
        public IdGenerator(TableStorage storage)
        {
            tableIds = new ConcurrentDictionary <string, int>();

            using (var snapshot = storage.CreateSnapshot())
            {
                var pages = storage.Pages.TableName;
                tableIds.TryAdd(pages, ReadLastIdFromTable(storage.Pages, snapshot));

                var usage = storage.Usage.TableName;
                tableIds.TryAdd(usage, ReadLastIdFromTable(storage.Usage, snapshot));

                var signatures = storage.Signatures.TableName;
                tableIds.TryAdd(signatures, ReadLastIdFromTable(storage.Signatures, snapshot));
            }
        }
Ejemplo n.º 7
0
        public void SetupDatabaseIdAndSchemaVersion()
        {
            using (var snapshot = storage.CreateSnapshot())
            {
                var idSlice            = new Slice("id");
                var schemaVersionSlice = new Slice("schema_version");

                Guid   id;
                string schemaVersion;

                var read = storage.Details.Read(snapshot, idSlice, null);
                if (read == null) // new db
                {
                    id            = Guid.NewGuid();
                    schemaVersion = SchemaVersion;
                    using (var writeIdBatch = new WriteBatch())
                    {
                        storage.Details.Add(writeIdBatch, idSlice, id.ToByteArray());
                        storage.Details.Add(writeIdBatch, schemaVersionSlice, schemaVersion);
                        storage.Write(writeIdBatch);
                    }
                }
                else
                {
                    if (read.Reader.Length != 16) //precaution - might prevent NRE in edge cases
                    {
                        throw new InvalidDataException("Failed to initialize Voron transactional storage. Possible data corruption. (no db id)");
                    }

                    using (var stream = read.Reader.AsStream())
                        using (var reader = new BinaryReader(stream))
                        {
                            id = new Guid(reader.ReadBytes((int)stream.Length));
                        }

                    var schemaRead = storage.Details.Read(snapshot, schemaVersionSlice, null);
                    if (schemaRead == null)
                    {
                        throw new InvalidDataException("Failed to initialize Voron transactional storage. Possible data corruption. (no schema version)");
                    }

                    schemaVersion = schemaRead.Reader.ToStringValue();
                }

                storage.SetDatabaseIdAndSchemaVersion(id, schemaVersion);
            }
        }
Ejemplo n.º 8
0
        public void PulseTransaction()
        {
            try
            {
                storageActionsAccessor.ExecuteBeforeStorageCommit();

                storage.Write(writeBatch.Value);

                snapshot.Value.Dispose();
                writeBatch.Value.Dispose();

                snapshot.Value   = storage.CreateSnapshot();
                writeBatch.Value = new WriteBatch {
                    DisposeAfterWrite = writeBatch.Value.DisposeAfterWrite
                };
            }
            finally
            {
                storageActionsAccessor.ExecuteAfterStorageCommit();
            }
        }
Ejemplo n.º 9
0
        private void ExecuteBatch(Action <IStorageActionsAccessor> action)
        {
            var snapshotRef   = new Reference <SnapshotReader>();
            var writeBatchRef = new Reference <WriteBatch>();

            var errorInUserAction = false;

            try
            {
                snapshotRef.Value   = tableStorage.CreateSnapshot();
                writeBatchRef.Value = new WriteBatch {
                    DisposeAfterWrite = false
                };                                                                  // prevent from disposing after write to allow read from batch OnStorageCommit
                var storageActionsAccessor = new StorageActionsAccessor(tableStorage, writeBatchRef, snapshotRef, idGenerator, bufferPool, uuidGenerator, fileCodecs);
                if (disableBatchNesting.Value == null)
                {
                    current.Value = storageActionsAccessor;
                }

                errorInUserAction = true;
                action(storageActionsAccessor);
                errorInUserAction = false;
                storageActionsAccessor.Commit();

                tableStorage.Write(writeBatchRef.Value);
            }
            catch (Exception e)
            {
                var exception = e;
                var ae        = e as AggregateException;
                if (ae != null)
                {
                    exception = ae.ExtractSingleInnerException();
                }

                Exception _;
                if (TransactionalStorageHelper.IsVoronOutOfMemoryException(exception) ||
                    TransactionalStorageHelper.IsWriteConflict(e, out _))
                {
                    throw;
                }

                if (errorInUserAction == false)
                {
                    Log.ErrorException("Failed to execute transaction. Most likely something is really wrong here.", e);
                }

                throw;
            }
            finally
            {
                if (snapshotRef.Value != null)
                {
                    snapshotRef.Value.Dispose();
                }

                if (writeBatchRef.Value != null)
                {
                    writeBatchRef.Value.Dispose();
                }
            }
        }