Пример #1
0
        public TransactionService(HeaderPage header, DiskService disk, WalIndexService walIndex)
        {
            // retain instances
            _header   = header;
            _disk     = disk;
            _walIndex = walIndex;

            // create new transactionID
            _transactionID = walIndex.NextTransactionID();
            _startTime     = DateTime.UtcNow;
        }
Пример #2
0
        public TransactionService(HeaderPage header, LockService locker, DiskService disk, WalIndexService walIndex, int maxTransactionSize, TransactionMonitor monitor, bool queryOnly)
        {
            // retain instances
            _header   = header;
            _locker   = locker;
            _disk     = disk;
            _walIndex = walIndex;
            _monitor  = monitor;

            this.QueryOnly          = queryOnly;
            this.MaxTransactionSize = maxTransactionSize;

            // create new transactionID
            _transactionID = walIndex.NextTransactionID();
            _startTime     = DateTime.UtcNow;
            _reader        = _disk.GetReader();
        }
Пример #3
0
        public TransactionService(HeaderPage header, LockService locker, DiskService disk, WalIndexService walIndex, int maxTransactionSize, Action <uint> done)
        {
            // retain instances
            _header             = header;
            _locker             = locker;
            _disk               = disk;
            _walIndex           = walIndex;
            _maxTransactionSize = maxTransactionSize;
            _done               = done;

            // create new transactionID
            _transactionID = walIndex.NextTransactionID();
            _startTime     = DateTime.UtcNow;
            _reader        = _disk.GetReader();

            // enter transaction locker to avoid 2 transactions in same thread
            _locker.EnterTransaction();
        }
Пример #4
0
        /// <summary>
        /// Return added pages when occurs an rollback transaction (run this only in rollback). Create new transactionID and add into
        /// Log file all new pages as EmptyPage in a linked order - also, update SharedPage before store
        /// </summary>
        private void ReturnNewPages()
        {
            // create new transaction ID
            var transactionID = _walIndex.NextTransactionID();

            // now lock header to update LastTransactionID/FreePageList
            lock (_header)
            {
                // persist all empty pages into wal-file
                var pagePositions = new Dictionary <uint, PagePosition>();

                IEnumerable <PageBuffer> source()
                {
                    // create list of empty pages with forward link pointer
                    for (var i = 0; i < _transPages.NewPages.Count; i++)
                    {
                        var pageID = _transPages.NewPages[i];
                        var next   = i < _transPages.NewPages.Count - 1 ? _transPages.NewPages[i + 1] : _header.FreeEmptyPageID;

                        var buffer = _disk.NewPage();

                        var page = new BasePage(buffer, pageID, PageType.Empty)
                        {
                            NextPageID    = next,
                            TransactionID = transactionID
                        };

                        yield return(page.UpdateBuffer());

                        // update wal
                        pagePositions[pageID] = new PagePosition(pageID, buffer.Position);

                        if (_disposed)
                        {
                            yield break;
                        }
                    }

                    // update header page with my new transaction ID
                    _header.TransactionID   = transactionID;
                    _header.FreeEmptyPageID = _transPages.NewPages[0];
                    _header.IsConfirmed     = true;

                    // clone header buffer
                    var buf   = _header.UpdateBuffer();
                    var clone = _disk.NewPage();

                    Buffer.BlockCopy(buf.Array, buf.Offset, clone.Array, clone.Offset, clone.Count);

                    yield return(clone);
                };

                // create a header save point before any change
                var safepoint = _header.Savepoint();

                try
                {
                    // write all pages (including new header)
                    _disk.WriteAsync(source());
                }
                catch
                {
                    // must revert all header content if any error occurs during header change
                    _header.Restore(safepoint);
                    throw;
                }

                // now confirm this transaction to wal
                _walIndex.ConfirmTransaction(transactionID, pagePositions.Values);
            }
        }