anchor.diff:  
   % Transactional wrapper for conducting a channel search.
   
  -search_rows(Node, Channel, RowsBack, SearchString) ->
  -  Transaction = fun() ->
  -    get_search_results(Node, Channel, RowsBack, SearchString)
  +search_rows(Channel, RowsBack, SearchString) ->
  +  Transaction = fun() ->
  +    get_search_results(Channel, RowsBack, SearchString)
     end,
     case mnesia:transaction(Transaction) of
       { aborted, Reason } ->
  
positive.code: 
  
  -module(atc872).
  -export([start/1, add_row/7, add_row/8, fetch_rows/5, search_rows/4, archiver/2]).
  
  
  
  
  % Start hook.  Takes arguments:
  % - TCP port for the web server.
  % - Node ID number.
  % - Number of nodes in the cluster.
  % - Number of rows to cache before the archiver writes them to disk.
  % Initialises Mnesia and starts the Misultin web server.
  
  start([ Port, Node, Nodes, CachedRows ]) ->
    process_flag(trap_exit, true),
  
    error_logger:info_msg("Starting node: ~s (total nodes: ~s)~n", [ Node, Nodes ]),
    error_logger:info_msg("Caching ~s rows~n", [ CachedRows ]),
    error_logger:info_msg("Initialising Mnesia~n"),
  
  
negative.code: 
  % Return all rows added after the given row ID ("LastRow").
  
  get_rows(Channel, LastRow, RowsBack) ->
    case mnesia:read({ rows, { last, Channel, node() } }) of
      [ { _, _, Last } ] ->
        if
          Last > LastRow ->
            Rows = lists:foldl(fun(E, A) ->
              [ { _, _, R } ] = mnesia:read({ rows, { node(), Channel, E } }),
              [ R ] ++ A
            end, [], lists:sublist(lists:seq(Last, LastRow + 1, -1), RowsBack)),
            { Last, Rows }
  