Refactor TxState to separate read/write ops

By separating the read operations of the transaction state and the write
operations of the transaction state into separate interfaces we can
allow for API clients that only need to be able to read the state.

By ensuring that there is no overlap between the methods used for
reading and the methods used for writing (including in the internal
implementation - don’t use reader methods to access state for writing)
we can ensure that reading state never initialises lazy data structures.

When reading never initialises state we can allow reader methods to
return read-only objects when there is no state present, allowing us to
concentrate null checks to only a few places, and make the code that
reads the state simpler by having fewer special cases to deal with.
Looking through the usages of these methods, what we do is direct iteration, never any fancy iterator transformation.

Looking through the implementations of these methods, it just returns collections that already exist, so there is no cost for these signatures to be `Iterable`, but it would be more code to have them be `Iterator`, so I think it makes sense to have `Iterable` in the places that we do.

For the things that are `Iterator` in the signature, we do perform transformations on those, such as augmenting, filtering, transforming, et.c., so those make sense to have as `Iterator`.

This being an internal interface, each method should be what we need it to be, striving towards uniformity has no value in of itself.