protected static DatabaseAccessProvider <IPlatformDatabaseServices> GetProviderForDatabase(IRuntimeDatabaseConfiguration configurationForDatabase,
                                                                                                   DatabaseSettingsSerialization.User user, DatabaseAccessProvider <IPlatformDatabaseServices> systemDatabaseProvider,
                                                                                                   IDictionary <string, DatabaseAccessProvider <IPlatformDatabaseServices> > providersByIdentifier,
                                                                                                   IDictionary <string, ITransactionManager> transactionManagersByIdentifier)
        {
            if (configurationForDatabase == null)
            {
                return(systemDatabaseProvider);
            }

            bool supportsUnifiedTransactionManager = (user == DatabaseSettingsSerialization.User.Admin) ||
                                                     Settings.GetBool(Settings.Configs.SupportUnifiedMDC);

            var systemConfig = systemDatabaseProvider.DatabaseServices.DatabaseConfiguration;

            string managerIdentifier = supportsUnifiedTransactionManager ?
                                       configurationForDatabase.Username
                : configurationForDatabase.DatabaseIdentifier;

            string systemManagerIdentifier = supportsUnifiedTransactionManager ?
                                             systemConfig.Username
                : systemConfig.DatabaseIdentifier;

            bool sameIdentifier = managerIdentifier.EqualsIgnoreCase(systemManagerIdentifier);
            // If using the system manager to access the system database, we can use the SystemProvider
            bool sameDatabase = configurationForDatabase.DatabaseIdentifier.EqualsIgnoreCase(systemConfig.DatabaseIdentifier);

            if (sameIdentifier && sameDatabase)
            {
                return(systemDatabaseProvider);
            }

            // In unified MDC scenarios, we want to use a provider with a shared transaction manager
            // while keeping the original configuration that uses the correct database identifier
            string providerIdentifier = managerIdentifier + (supportsUnifiedTransactionManager ? "-" + configurationForDatabase.DatabaseIdentifier : "");
            DatabaseAccessProvider <IPlatformDatabaseServices> provider;

            if (!providersByIdentifier.TryGetValue(providerIdentifier, out provider))
            {
                lock (providersByIdentifier) {
                    if (!providersByIdentifier.TryGetValue(providerIdentifier, out provider))
                    {
                        ITransactionManager manager = sameIdentifier ? systemDatabaseProvider.TransactionManager : null;
                        if (manager == null && !transactionManagersByIdentifier.TryGetValue(managerIdentifier, out manager))
                        {
                            var services = PlatformDatabasePluginProvider
                                           .GetImplementation(configurationForDatabase.ProviderKey())
                                           .GetPlatformDatabaseServices(configurationForDatabase);
                            manager = services.TransactionService.CreateTransactionManager();
                            transactionManagersByIdentifier.Add(managerIdentifier, manager);
                        }

                        // TODO: Check with the Stack Team if we can optimized this
                        var dapServices = PlatformDatabasePluginProvider
                                          .GetImplementation(configurationForDatabase.ProviderKey())
                                          .GetPlatformDatabaseServices(configurationForDatabase);

                        dapServices.IntrospectionService.QueryTimeout = IntrospectionQueryTimeout;
                        provider = new DatabaseAccessProvider <IPlatformDatabaseServices>(
                            dapServices,
                            manager);

                        providersByIdentifier.Add(providerIdentifier, provider);
                    }
                }
            }
            return(provider);
        }
Ejemplo n.º 2
0
        protected static DatabaseAccessProvider <IPlatformDatabaseServices> GetProviderForDatabase(IRuntimeDatabaseConfiguration configurationForDatabase,
                                                                                                   DatabaseSettingsSerialization.User user, DatabaseAccessProvider <IPlatformDatabaseServices> baseProvider,
                                                                                                   IDictionary <string, DatabaseAccessProvider <IPlatformDatabaseServices> > providersByIdentifier,
                                                                                                   IDictionary <string, ITransactionManager> transactionManagersByIdentifier)
        {
            if (configurationForDatabase == null)
            {
                return(baseProvider);
            }

            // ***************** MDC STUFF ***************************
            var databaseConfig = baseProvider.DatabaseServices.DatabaseConfiguration;

            string managerIdentifier         = configurationForDatabase.Username;
            string databaseManagerIdentifier = databaseConfig.Username;

            bool sameIdentifier = managerIdentifier.EqualsIgnoreCase(databaseManagerIdentifier);
            // If using the system manager to access the system database, we can use the SystemProvider
            bool sameDatabase = configurationForDatabase.DatabaseIdentifier.EqualsIgnoreCase(databaseConfig.DatabaseIdentifier);

            if (sameIdentifier && sameDatabase)
            {
                return(baseProvider);
            }

            // In unified MDC scenarios, we want to use a provider with a shared transaction manager
            // while keeping the original configuration that uses the correct database identifier
            string providerIdentifier = managerIdentifier + "-" + configurationForDatabase.DatabaseIdentifier;
            DatabaseAccessProvider <IPlatformDatabaseServices> provider;

            if (!providersByIdentifier.TryGetValue(providerIdentifier, out provider))
            {
                lock (providersByIdentifier) {
                    if (!providersByIdentifier.TryGetValue(providerIdentifier, out provider))
                    {
                        ITransactionManager manager = sameIdentifier ? baseProvider.TransactionManager : null;
                        if (manager == null && !transactionManagersByIdentifier.TryGetValue(managerIdentifier, out manager))
                        {
                            var services = PlatformDatabasePluginProvider
                                           .GetImplementation(configurationForDatabase.DatabaseProvider.Key)
                                           .GetPlatformDatabaseServices(configurationForDatabase);
                            manager = services.TransactionService.CreateTransactionManager();
                            transactionManagersByIdentifier.Add(managerIdentifier, manager);
                        }

                        // TODO: Check with the Stack Team if we can optimized this
                        var dapServices = PlatformDatabasePluginProvider
                                          .GetImplementation(configurationForDatabase.DatabaseProvider.Key)
                                          .GetPlatformDatabaseServices(configurationForDatabase);

                        provider = new DatabaseAccessProvider <IPlatformDatabaseServices>(
                            dapServices,
                            manager);

                        providersByIdentifier.Add(providerIdentifier, provider);
                    }
                }
            }
            // ***************** MDC STUFF ***************************
            return(provider);
        }