@Override protected void undo(NavigableMap<byte[], NavigableMap<byte[], Update>> persisted) throws Exception { if (persisted.isEmpty()) { return; } // NOTE: we use Delete with the write pointer as the specific version to delete. List<Delete> deletes = Lists.newArrayList(); for (Map.Entry<byte[], NavigableMap<byte[], Update>> row : persisted.entrySet()) { DeleteBuilder delete = tableUtil.buildDelete(row.getKey()); delete.setAttribute(TX_MAX_LIFETIME_MILLIS_KEY, txMaxLifetimeMillis); for (Map.Entry<byte[], Update> column : row.getValue().entrySet()) { // we want support tx and non-tx modes if (tx != null) { delete.setAttribute(TxConstants.TX_ROLLBACK_ATTRIBUTE_KEY, new byte[0]); // TODO: hijacking timestamp... bad delete.deleteColumn(columnFamily, column.getKey(), tx.getWritePointer()); } else { delete.deleteColumns(columnFamily, column.getKey()); } } deletes.add(delete.build()); } if (!deletes.isEmpty()) { hbaseDelete(deletes); } }
@Override protected void undo(NavigableMap<byte[], NavigableMap<byte[], Update>> persisted) throws Exception { if (persisted.isEmpty()) { return; } // NOTE: we use Delete with the write pointer as the specific version to delete. List<Delete> deletes = Lists.newArrayList(); for (Map.Entry<byte[], NavigableMap<byte[], Update>> row : persisted.entrySet()) { DeleteBuilder delete = tableUtil.buildDelete(row.getKey()); delete.setAttribute(TX_MAX_LIFETIME_MILLIS_KEY, txMaxLifetimeMillis); for (Map.Entry<byte[], Update> column : row.getValue().entrySet()) { // we want support tx and non-tx modes if (tx != null) { delete.setAttribute(TxConstants.TX_ROLLBACK_ATTRIBUTE_KEY, new byte[0]); // TODO: hijacking timestamp... bad delete.deleteColumn(columnFamily, column.getKey(), tx.getWritePointer()); } else { delete.deleteColumns(columnFamily, column.getKey()); } } deletes.add(delete.build()); } if (!deletes.isEmpty()) { hbaseDelete(deletes); } }