Exemple #1
0
        public async Task <bool> AcquireLockAsync(int millisecondsTimeout)
        {
            if (!_dbFactory.Configured)
            {
                // if we aren't configured then we're in an install state, in which case we have no choice but to assume we can acquire
                return(true);
            }

            _logger.LogDebug("Acquiring lock...");

            var tempId = Guid.NewGuid().ToString();

            IUmbracoDatabase?db = null;

            try
            {
                db = _dbFactory.CreateDatabase();


                _hasTable = db !.HasTable(Cms.Core.Constants.DatabaseSchema.Tables.KeyValue);
                if (!_hasTable)
                {
                    _logger.LogDebug("The DB does not contain the required table so we must be in an install state. We have no choice but to assume we can acquire.");
                    _acquireWhenTablesNotAvailable = true;
                    return(true);
                }

                db !.BeginTransaction(IsolationLevel.Serializable);

                var result = InsertLockRecord(tempId, db); //we change the row to a random Id to signal other MainDom to shutdown
                if (result == RecordPersistenceType.Insert)
                {
                    // if we've inserted, then there was no MainDom so we can instantly acquire

                    InsertLockRecord(_lockId, db); // so update with our appdomain id
                    _logger.LogDebug("Acquired with ID {LockId}", _lockId);
                    return(true);
                }

                // if we've updated, this means there is an active MainDom, now we need to wait to
                // for the current MainDom to shutdown which also requires releasing our write lock
            }
            catch (Exception ex)
            {
                // unexpected
                _logger.LogError(ex, "Unexpected error, cannot acquire MainDom");
                _errorDuringAcquiring = true;
                return(false);
            }
            finally
            {
                db?.CompleteTransaction();
                db?.Dispose();
            }


            return(await WaitForExistingAsync(tempId, millisecondsTimeout));
        }
Exemple #2
0
        private IUmbracoDatabase GetSqlCeDatabase(string cstr, ILogger logger)
        {
            var f = new UmbracoDatabaseFactory(
                cstr,
                Constants.DatabaseProviders.SqlCe,
                logger,
                new Lazy <IMapperCollection>(() => new MapperCollection(Enumerable.Empty <BaseMapper>())));

            return(f.CreateDatabase());
        }
        private IUmbracoDatabase GetDatabase()
        {
            if (_db != null)
            {
                return(_db);
            }

            _db = _dbFactory.CreateDatabase();
            return(_db);
        }
Exemple #4
0
        // FIXME: should run on LocalDb same as NPoco tests!

        private IUmbracoDatabase GetSqlServerDatabase(ILogger logger)
        {
            IScopeProvider f       = null;
            var            l       = new Lazy <IScopeProvider>(() => f);
            var            factory = new UmbracoDatabaseFactory(
                "server=.\\SQLExpress;database=YOURDB;user id=YOURUSER;password=YOURPASS",
                Constants.DatabaseProviders.SqlServer,
                logger,
                new Lazy <IMapperCollection>(() => new MapperCollection(Enumerable.Empty <BaseMapper>())));

            return(factory.CreateDatabase());
        }
        public void Cant_Connect_To_SqlDatabase_Because_Of_Network()
        {
            const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco";
            const string providerName     = Constants.DbProviderNames.SqlServer;
            var          factory          = new UmbracoDatabaseFactory(connectionString, providerName, Mock.Of <ILogger>(), new Lazy <IMapperCollection>(() => Mock.Of <IMapperCollection>()));

            using (var database = factory.CreateDatabase())
            {
                Assert.Throws <SqlException>(
                    () => database.Fetch <dynamic>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"));
            }
        }
Exemple #6
0
        public void Cant_Connect_To_SqlDatabase_With_Invalid_User()
        {
            const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=x;password=umbraco";
            const string providerName     = Constants.DbProviderNames.SqlServer;
            var          factory          = new UmbracoDatabaseFactory(Mock.Of <ILogger <UmbracoDatabaseFactory> >(), NullLoggerFactory.Instance, connectionString, providerName, new Lazy <IMapperCollection>(() => Mock.Of <IMapperCollection>()), TestHelper.DbProviderFactoryCreator, TestHelper.DatabaseSchemaCreatorFactory);

            using (var database = factory.CreateDatabase())
            {
                Assert.Throws <SqlException>(
                    () => database.Fetch <dynamic>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"));
            }
        }
Exemple #7
0
        public async Task <bool> AcquireLockAsync(int millisecondsTimeout)
        {
            if (!_dbFactory.Configured)
            {
                // if we aren't configured then we're in an install state, in which case we have no choice but to assume we can acquire
                return(true);
            }

            if (!(_dbFactory.SqlContext.SqlSyntax is SqlServerSyntaxProvider sqlServerSyntaxProvider))
            {
                throw new NotSupportedException("SqlMainDomLock is only supported for Sql Server");
            }

            _sqlServerSyntax = sqlServerSyntaxProvider;

            _logger.Debug <SqlMainDomLock>("Acquiring lock...");

            var tempId = Guid.NewGuid().ToString();

            IUmbracoDatabase db = null;

            try
            {
                db = _dbFactory.CreateDatabase();

                _hasTable = db.HasTable(Constants.DatabaseSchema.Tables.KeyValue);
                if (!_hasTable)
                {
                    // the Db does not contain the required table, we must be in an install state we have no choice but to assume we can acquire
                    return(true);
                }

                db.BeginTransaction(IsolationLevel.ReadCommitted);

                try
                {
                    // wait to get a write lock
                    _sqlServerSyntax.WriteLock(db, TimeSpan.FromMilliseconds(millisecondsTimeout), Constants.Locks.MainDom);
                }
                catch (SqlException ex)
                {
                    if (IsLockTimeoutException(ex))
                    {
                        _logger.Error <SqlMainDomLock>(ex, "Sql timeout occurred, could not acquire MainDom.");
                        _errorDuringAcquiring = true;
                        return(false);
                    }

                    // unexpected (will be caught below)
                    throw;
                }

                var result = InsertLockRecord(tempId, db); //we change the row to a random Id to signal other MainDom to shutdown
                if (result == RecordPersistenceType.Insert)
                {
                    // if we've inserted, then there was no MainDom so we can instantly acquire

                    InsertLockRecord(_lockId, db); // so update with our appdomain id
                    _logger.Debug <SqlMainDomLock, string>("Acquired with ID {LockId}", _lockId);
                    return(true);
                }

                // if we've updated, this means there is an active MainDom, now we need to wait to
                // for the current MainDom to shutdown which also requires releasing our write lock
            }
            catch (Exception ex)
            {
                // unexpected
                _logger.Error <SqlMainDomLock>(ex, "Unexpected error, cannot acquire MainDom");
                _errorDuringAcquiring = true;
                return(false);
            }
            finally
            {
                db?.CompleteTransaction();
                db?.Dispose();
            }


            return(await WaitForExistingAsync(tempId, millisecondsTimeout).ConfigureAwait(false));
        }