unqlite-ruby icon indicating copy to clipboard operation
unqlite-ruby copied to clipboard

Data loss when fetch() fails in-between store() calls

Open djurczak opened this issue 12 years ago • 3 comments

If we store multiple values in succession (e.g. in a loop) and there is a fetch() call in-between those store() calls that fails we lose all the data that had been added so far.

This happens because in rb_unqlite_raise() (ext/unqlite/unqlite_exception.c) we call unqlite_rollback() unless the UnQLite error code is either UNQLITE_BUSY or UNQLITE_NOTIMPLEMENTED.

Now, since fetch() is a read-only operation I'd argue that we should avoid calling rollback() in case we fail to find an entry.

A basic fix is pretty trivial but I didn't want to submit it yet since you might instead choose to do slightly more extensive refactoring of the exception code.

I added testcases that generate the problem.

djurczak avatar Jul 23 '13 11:07 djurczak

Nice Daniel, we need to do a refactor on this exception code for sure! I'll use these tests and start to refactor, thanks!

danieltdt avatar Jul 24 '13 12:07 danieltdt

Cool. In my local version I just quickly addedUNQLITE_NOT_FOUND to those errors that don't generate a rollback() call. But as I said, I am not sure if raising an exception is a good behaviour for fetch() so some more extensive work might be necessary. Which is why I didn't post my fix.

djurczak avatar Jul 24 '13 15:07 djurczak

Tests merged (c1840adb0c) and removed the auto rollback on errors (a84c082e89). To get auto-rollback one could now do this instead:

db.transaction do
  db.store "key", "val"
  db.fetch "xxx"
end

larsch avatar Aug 03 '13 14:08 larsch