private ModelAndView startTransaction(
      Repository repository, HttpServletRequest request, HttpServletResponse response)
      throws IOException, ClientHTTPException, ServerHTTPException {
    ProtocolUtil.logRequestParameters(request);
    Map<String, Object> model = new HashMap<String, Object>();

    IsolationLevel isolationLevel = null;
    final String isolationLevelString = request.getParameter(Protocol.ISOLATION_LEVEL_PARAM_NAME);
    if (isolationLevelString != null) {
      final IRI level = SimpleValueFactory.getInstance().createIRI(isolationLevelString);

      // FIXME this needs to be adapted to accommodate custom isolation levels
      // from third party stores.
      for (IsolationLevel standardLevel : IsolationLevels.values()) {
        if (standardLevel.getURI().equals(level)) {
          isolationLevel = standardLevel;
          break;
        }
      }
    }

    try {
      Transaction txn = new Transaction(repository);
      txn.begin(isolationLevel);

      UUID txnId = txn.getID();

      ActiveTransactionRegistry.INSTANCE.register(txn);

      model.put(SimpleResponseView.SC_KEY, SC_CREATED);
      final StringBuffer txnURL = request.getRequestURL();
      txnURL.append("/" + txnId.toString());
      Map<String, String> customHeaders = new HashMap<String, String>();
      customHeaders.put("Location", txnURL.toString());
      model.put(SimpleResponseView.CUSTOM_HEADERS_KEY, customHeaders);
      return new ModelAndView(SimpleResponseView.getInstance(), model);
    } catch (RepositoryException | InterruptedException | ExecutionException e) {
      throw new ServerHTTPException("Transaction start error: " + e.getMessage(), e);
    }
  }