/**
   * Check the autoCommit and Transaction Isolation levels of the DataSource.
   *
   * <p>If autoCommit is true this could be a real problem.
   *
   * <p>If the Isolation level is not READ_COMMITED then optimistic concurrency checking may not
   * work as expected.
   */
  private boolean checkDataSource(ServerConfig serverConfig) {

    if (serverConfig.getDataSource() == null) {
      if (serverConfig.getDataSourceConfig().isOffline()) {
        // this is ok - offline DDL generation etc
        return false;
      }
      throw new RuntimeException("DataSource not set?");
    }

    Connection c = null;
    try {
      c = serverConfig.getDataSource().getConnection();

      if (c.getAutoCommit()) {
        String m = "DataSource [" + serverConfig.getName() + "] has autoCommit defaulting to true!";
        logger.warning(m);
      }

      return true;

    } catch (SQLException ex) {
      throw new PersistenceException(ex);

    } finally {
      if (c != null) {
        try {
          c.close();
        } catch (SQLException ex) {
          logger.log(Level.SEVERE, null, ex);
        }
      }
    }
  }
 /** Set the DataSource if it has not already been set. */
 private void setDataSource(ServerConfig config) {
   if (config.getDataSource() == null) {
     DataSource ds = getDataSourceFromConfig(config);
     config.setDataSource(ds);
   }
 }
  /** Create the implementation from the configuration. */
  public SpiEbeanServer createServer(ServerConfig serverConfig) {

    synchronized (this) {
      setNamingConvention(serverConfig);

      BootupClasses bootupClasses = getBootupClasses(serverConfig);

      setDataSource(serverConfig);
      // check the autoCommit and Transaction Isolation
      boolean online = checkDataSource(serverConfig);

      // determine database platform (Oracle etc)
      setDatabasePlatform(serverConfig);
      if (serverConfig.getDbEncrypt() != null) {
        // use a configured DbEncrypt rather than the platform default
        serverConfig.getDatabasePlatform().setDbEncrypt(serverConfig.getDbEncrypt());
      }

      DatabasePlatform dbPlatform = serverConfig.getDatabasePlatform();

      PstmtBatch pstmtBatch = null;

      if (dbPlatform.getName().startsWith("oracle")) {
        PstmtDelegate pstmtDelegate = serverConfig.getPstmtDelegate();
        if (pstmtDelegate == null) {
          // try to provide the
          pstmtDelegate = getOraclePstmtDelegate(serverConfig.getDataSource());
        }
        if (pstmtDelegate != null) {
          // We can support JDBC batching with Oracle
          // via OraclePreparedStatement
          pstmtBatch = new OraclePstmtBatch(pstmtDelegate);
        }
        if (pstmtBatch == null) {
          // We can not support JDBC batching with Oracle
          logger.warning("Can not support JDBC batching with Oracle without a PstmtDelegate");
          serverConfig.setPersistBatching(false);
        }
      }

      // inform the NamingConvention of the associated DatabasePlaform
      serverConfig.getNamingConvention().setDatabasePlatform(serverConfig.getDatabasePlatform());

      ServerCacheManager cacheManager = getCacheManager(serverConfig);

      int uniqueServerId = serverId.incrementAndGet();
      SpiBackgroundExecutor bgExecutor = createBackgroundExecutor(serverConfig, uniqueServerId);

      InternalConfiguration c =
          new InternalConfiguration(
              xmlConfig,
              clusterManager,
              cacheManager,
              bgExecutor,
              serverConfig,
              bootupClasses,
              pstmtBatch);

      DefaultServer server = new DefaultServer(c, cacheManager);

      cacheManager.init(server);

      MBeanServer mbeanServer;
      ArrayList<?> list = MBeanServerFactory.findMBeanServer(null);
      if (list.size() == 0) {
        // probably not running in a server
        mbeanServer = MBeanServerFactory.createMBeanServer();
      } else {
        // use the first MBeanServer
        mbeanServer = (MBeanServer) list.get(0);
      }

      server.registerMBeans(mbeanServer, uniqueServerId);

      // generate and run DDL if required
      executeDDL(server, online);

      // initialise prior to registering with clusterManager
      server.initialise();

      if (online) {
        if (clusterManager.isClustering()) {
          // register the server once it has been created
          clusterManager.registerServer(server);
        }

        // warm the cache in 30 seconds
        int delaySecs = GlobalProperties.getInt("ebean.cacheWarmingDelay", 30);
        long sleepMillis = 1000 * delaySecs;

        if (sleepMillis > 0) {
          Timer t = new Timer("EbeanCacheWarmer", true);
          t.schedule(new CacheWarmer(server), sleepMillis);
        }
      }

      // start any services after registering with clusterManager
      server.start();
      return server;
    }
  }