private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throws MetaException {
    Table newTable = context.getNewTable();
    Map<String, String> parameters = newTable.getParameters();
    if (parameters == null || parameters.isEmpty()) {
      return;
    }
    Set<String> keys = new HashSet<>(parameters.keySet());
    String transactionalValue = null;
    boolean transactionalValuePresent = false;
    boolean isTransactionalPropertiesPresent = false;
    String transactionalPropertiesValue = null;
    boolean hasValidTransactionalValue = false;

    for (String key : keys) {
      if(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.equalsIgnoreCase(key)) {
        transactionalValuePresent = true;
        transactionalValue = parameters.get(key);
        parameters.remove(key);
      }
      if(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
        isTransactionalPropertiesPresent = true;
        transactionalPropertiesValue = parameters.get(key);
        // Do not remove the parameter yet, because we have separate initialization routine
        // that will use it down below.
      }
    }
    Table oldTable = context.getOldTable();
    String oldTransactionalValue = null;
    String oldTransactionalPropertiesValue = null;
    for (String key : oldTable.getParameters().keySet()) {
      if (hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.equalsIgnoreCase(key)) {
        oldTransactionalValue = oldTable.getParameters().get(key);
      }
      if (hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
        oldTransactionalPropertiesValue = oldTable.getParameters().get(key);
      }
    }

    if (transactionalValuePresent && "false".equalsIgnoreCase(transactionalValue)) {
      transactionalValuePresent = false;
      transactionalValue = null;
    }

    if (transactionalValuePresent) {
      if (oldTable.getTableType().equals(TableType.MANAGED_TABLE.toString())
              && newTable.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) {
        throw new MetaException(Warehouse.getQualifiedName(newTable) +
                " cannot be converted to external table as it is transactional table.");
      }

      //normalize prop name
      parameters.put(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL, transactionalValue);
    }
    if ("true".equalsIgnoreCase(transactionalValue) && !"true".equalsIgnoreCase(oldTransactionalValue)) {
      if(!isTransactionalPropertiesPresent) {
        normalizeTransactionalPropertyDefault(newTable);
        isTransactionalPropertiesPresent = true;
        transactionalPropertiesValue = DEFAULT_TRANSACTIONAL_PROPERTY;
      }
      // We only need to check conformance if alter table enabled acid.
      // INSERT_ONLY tables don't have to conform to ACID requirement like ORC or bucketing.
      boolean isFullAcid = transactionalPropertiesValue == null
          || !"insert_only".equalsIgnoreCase(transactionalPropertiesValue);
      if (isFullAcid && !conformToAcid(newTable)) {
        throw new MetaException("The table must be stored using an ACID compliant "
            + "format (such as ORC): " + Warehouse.getQualifiedName(newTable));
      }

      if (newTable.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) {
        throw new MetaException(Warehouse.getQualifiedName(newTable) +
            " cannot be declared transactional because it's an external table");
      }
      if (isFullAcid) {
        validateTableStructure(context.getHandler(), newTable);
      }
      hasValidTransactionalValue = true;
    }



    if (oldTransactionalValue == null ? transactionalValue == null
                                     : oldTransactionalValue.equalsIgnoreCase(transactionalValue)) {
      //this covers backward compat cases where this prop may have been set already
      hasValidTransactionalValue = true;
    }

    if (!hasValidTransactionalValue && !MetaStoreUtils.isInsertOnlyTableParam(oldTable.getParameters())) {
      // if here, there is attempt to set transactional to something other than 'true'
      // and NOT the same value it was before
      throw new MetaException("TBLPROPERTIES with 'transactional'='true' cannot be unset: "
          + Warehouse.getQualifiedName(newTable));
    }

    if (isTransactionalPropertiesPresent) {
      // Now validate transactional_properties for the table.
      if (oldTransactionalValue == null) {
        // If this is the first time the table is being initialized to 'transactional=true',
        // any valid value can be set for the 'transactional_properties'.
        initializeTransactionalProperties(newTable);
      } else {
        // If the table was already marked as 'transactional=true', then the new value of
        // 'transactional_properties' must match the old value. Any attempt to alter the previous
        // value will throw an error. An exception will still be thrown if the previous value was
        // null and an attempt is made to set it. This behaviour can be changed in the future.
        if ((oldTransactionalPropertiesValue == null
            || !oldTransactionalPropertiesValue.equalsIgnoreCase(transactionalPropertiesValue))
            && !MetaStoreUtils.isInsertOnlyTableParam(oldTable.getParameters())) {
          throw new MetaException("TBLPROPERTIES with 'transactional_properties' cannot be "
              + "altered after the table is created");
        }
      }
    }
    checkSorted(newTable);
    if (TxnUtils.isAcidTable(newTable) && !TxnUtils.isTransactionalTable(oldTable)) {
      /* we just made an existing table full acid which wasn't acid before and it passed all checks
      initialize the Write ID sequence so that we can handle assigning ROW_IDs to 'original'
      files already present in the table. Not needed if oldTable is insertOnly.*/
      TxnStore t = TxnUtils.getTxnStore(getConf());
      //For now assume no partition may have > 10M files.  Perhaps better to count them.
      t.seedWriteId(new SeedTableWriteIdsRequest(newTable.getDbName(),
          newTable.getTableName(), 10000000));
    }
  }
once a table is marked transactional, you cannot go back.  Enforce this.
Also in current version, 'transactional_properties' of the table cannot be altered after
the table is created. Any attempt to alter it will throw a MetaException.
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java