Closed phraktle closed 9 years ago
When does this happen? Could you provide the error codes for both put and commit?
The put was throwing an "MDB_PAGE_FULL: Internal error - page has no more space" (the reasons are not yet obvious, but that's besides the point). However, the commit clobbered this with a "MDB_BAD_TXN: Transaction cannot recover - it must be aborted", so you couldn't see the underlying error.
Is the commit automatically aborted by LMDB when this happens? Or must it be aborted manually to release the transaction?
The transaction can only be aborted at this point. That's why the commit was throwing MDB_BAD_TXN.
I'm not sure if there's a resource leak if you don't call abort explicitly, but there's certainly no harm in doing so :)
Do you mind adding that to commit() in #24? I.e. call abort before throwing the exception?
With the try-with-resources pattern, that's what actually happens: if the commit failed, the close performs an abort at the end of the block (since self wasn't zeroed by the commit). Doing an abort in commit is confusing.
Plus this pattern takes care of handling any potential suppressed exceptions.
Yes, but what if you cannot use try-with-resources? Like when using ThreadLocal interceptors for example?
Then the caller has to ensure closing the resource they have opened. Just like for any other resource, e.g. a file handle.
I don't want to beat a dead horse but if the transaction knows that it cannot proceed why not abort right away? Just as a measure to prevent resource leaks. The user can still abort manually and this will be a no-op.
This a pretty abnormal situation so taking these extra measures might be appropriate?
The reason I'm resisting is that I think it's confusing for the commit API call to implicitly also try an abort. And it also makes proper exception handling there nastier (catch potential the exception from commit, then catch potential exception from abort, add that as a suppressed exception to the first Throwable, etc) – while try-with-resources does all this automatically.
In general, most lmdbjni API users will either do atomic get/put calls, or if they do multiple operations in a transaction, they would use try-with-resources (which is much better than the pattern proposed by the current lmdbjni readme).
Alright, let's settle on this approach.
Thanks ;)
the following pattern is broken:
When put throws an error, the commit still runs. Which causes the commit itself to throw an error, masking the original problem.