@Override
  public HTTPResponse update(HTTPRequest request, HTTPResponse response) {
    Key key = Key.create(request, response);
    Connection connection = getConnection();

    PreparedStatement statement = null;
    try {
      JdbcUtil.startTransaction(connection);
      statement =
          connection.prepareStatement(
              "update response set headers = ?, cachetime = ? where uri = ? and vary = ?");
      statement.setString(1, response.getHeaders().toJSON());
      statement.setTimestamp(2, new Timestamp(DateTimeUtils.currentTimeMillis()));
      statement.setString(3, key.getURI().toString());
      statement.setString(4, key.getVary().toJSON());
      statement.executeUpdate();
      connection.commit();
      return getImpl(connection, key);
    } catch (SQLException e) {
      JdbcUtil.rollback(connection);
      JdbcUtil.close(connection);
      throw new DataAccessException(e);
    } finally {
      JdbcUtil.endTransaction(connection);
      JdbcUtil.close(statement);
    }
  }
 @Override
 public void invalidate(final URI uri) {
   Connection connection = getConnection();
   PreparedStatement statement = null;
   try {
     JdbcUtil.startTransaction(connection);
     statement = connection.prepareStatement("delete from response where uri = ?");
     statement.setString(1, uri.toString());
     statement.executeUpdate();
     connection.commit();
   } catch (SQLException e) {
     JdbcUtil.rollback(connection);
     throw new DataAccessException("Unable to invalidate", e);
   } finally {
     JdbcUtil.endTransaction(connection);
     JdbcUtil.close(statement);
     JdbcUtil.close(connection);
   }
 }
  @Override
  public HTTPResponse insert(HTTPRequest request, HTTPResponse response) {
    Key key = Key.create(request, response);
    Connection connection = getConnection();

    String sql =
        "insert into response(uri, vary, status, headers, payload, mimeType, cachetime) values (?, ?, ?, ?, ?, ?, ?)";
    PreparedStatement statement = null;
    try {
      JdbcUtil.startTransaction(connection);
      invalidate(key, connection);
      statement = connection.prepareStatement(sql);
      statement.setString(1, key.getURI().toString());
      statement.setString(2, key.getVary().toJSON());
      statement.setInt(3, response.getStatus().getCode());
      statement.setString(4, response.getHeaders().toJSON());
      InputStream inputStream = null;
      if (response.hasPayload() && response.getPayload().isAvailable()) {
        statement.setString(6, response.getPayload().getMimeType().toString());
        inputStream = response.getPayload().getInputStream();
        statement.setBinaryStream(5, inputStream);
      } else {
        statement.setNull(5, Types.BLOB);
        statement.setNull(6, Types.VARCHAR);
      }
      statement.setTimestamp(7, new Timestamp(DateTimeUtils.currentTimeMillis()));
      try {
        statement.executeUpdate();
      } finally {
        IOUtils.closeQuietly(inputStream);
      }
      connection.commit();
      return getImpl(connection, key);
    } catch (SQLException e) {
      JdbcUtil.rollback(connection);
      JdbcUtil.close(connection);
      throw new DataAccessException(e);
    } finally {
      JdbcUtil.endTransaction(connection);
      JdbcUtil.close(statement);
    }
  }