The difference is simple:
With read committed, if between two consecutive read calls on the same key, the key has been updated by another transaction, the second read will return the new updated value:
1. Thread1: tx.begin()
2. Thread1: cache.get(k) returns v
3. Thread2: tx.begin()
4. Thread2: cache.get(k) returns v
5. Thread2: cache.put(k, v2)
6. Thread2: tx.commit()
7. Thread1: cache.get(k) returns v2!
With repeteable read, step 7 will still return v. So, the idea is that if you retrieve the same key multiple times within a transaction, you should use repeteable read.
Btw, as always, we have tests in the Infinispan code base that show this in action: