If I understand correctly, Mongo's contract is to always reacquire the snapshot (i.e. do saveState + restoreState) after each commit/abort.
There is (at least) one place in the code where this is not true. To demonstrate the issue I created a patch here: https://github.com/mongodb-partners/mongo/commits/v3.0-failure (on top of the current v3.0 branch)
The patch keeps track of live iterators and makes sure that they're not reused after commit. Here's the stack trace of invalidation failure: https://gist.github.com/igorcanadi/c15eb094583054a0918a
This is where the commit happens: https://github.com/mongodb/mongo/blob/master/src/mongo/db/catalog/index_create.cpp#L272, while `exec` plan executor is not yielding.
This issue is causing background index build concurrency problems for RocksDB, as evidenced by https://jira.mongodb.org/browse/SERVER-18744. We've encountered this in production.
It would also be good to add some invariants in the code to make sure this contract is respected, since it's a bit tricky behavior.
Let me know if I'm misunderstanding anything.