コード例 #1
0
ファイル: FileSetTests.cs プロジェクト: Bikeman868/RestDB
        public void should_roll_back_uncommitted_transactions_on_restart()
        {
            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _pageSize, _startUpLog), new DataFile(_dataFileInfo2, _pageSize, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, true, _startUpLog), new LogFile(_logFileInfo2, true, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            var databaseFactory  = SetupMock <IDatabaseFactory>();
            var pageStoreFactory = SetupMock <IPageStoreFactory>();

            var pageStore = pageStoreFactory.Open(_fileSet);
            var database  = databaseFactory.Open(pageStore);

            var transaction1 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction1,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 20,
                    Data           = new byte[] { 1, 2, 3 }
                }
            });
            database.CommitTransaction(transaction1);

            var transaction2 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction2,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 25,
                    Data           = new byte[] { 4, 5, 6 }
                }
            });
            database.CommitTransaction(transaction2);

            var transaction3 = database.BeginTransaction(null);

            _fileSet.Write(
                transaction3,
                new[] {
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 5,
                    Data           = new byte[] { 7, 8, 9 }
                },
                new PageUpdate
                {
                    SequenceNumber = 0,
                    PageNumber     = 1,
                    Offset         = 30,
                    Data           = new byte[] { 10, 11, 12 }
                }
            });
            database.CommitTransaction(transaction3);

            // Before the transaction is committed the page should be in its original state

            using (var originalPage = _pagePool.Get(1))
            {
                _fileSet.Read(originalPage);

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, originalPage.Data[i]);
                }
            }

            // Commit transactions to the log files but do not update the data files

            _fileSet.CommitTransaction(transaction1).Wait();
            _fileSet.CommitTransaction(transaction2).Wait();
            _fileSet.CommitTransaction(transaction3).Wait();

            // Shut down and close all the files

            _fileSet.Dispose();

            // Reopen all of the files

            _fileSet = new FileSet(
                new IDataFile[] { new DataFile(_dataFileInfo1, _startUpLog), new DataFile(_dataFileInfo2, _startUpLog) },
                new ILogFile[] { new LogFile(_logFileInfo1, false, _startUpLog), new LogFile(_logFileInfo2, false, _startUpLog) },
                _pagePoolFactory,
                _startUpLog);

            // Roll back all transactions

            ulong[] mustRollBackVersions;
            ulong[] canRollForwardVersions;
            _fileSet.GetIncompleteTransactions(out mustRollBackVersions, out canRollForwardVersions);

            _fileSet.RollBack(mustRollBackVersions);
            _fileSet.RollBack(canRollForwardVersions);

            // After rolling back the page should be unchanged in the data file

            using (var newPage = _pagePool.Get(1))
            {
                _fileSet.Read(newPage);

                for (var i = 0; i < _pageSize; i++)
                {
                    Assert.AreEqual(0, newPage.Data[i]);
                }
            }

            // There should be no incomplete transactions now

            _fileSet.GetIncompleteTransactions(out mustRollBackVersions, out canRollForwardVersions);

            Assert.AreEqual(0, mustRollBackVersions.Length);
            Assert.AreEqual(0, canRollForwardVersions.Length);
        }