How readonly txn.Reset and txn.Renew use?
Opened this issue · 4 comments
I create a read-only txn in a goroutine, then this txn will called in another goroutine frequently.
The scene is:
- four writer goroutines write to the db, then four reader goroutines read this db(this four readers don't share txn.)
- each time, a reader read some data from db (such as 20 key one time),if db has not enough data, return, after 50ms, read again.
so I call txn.Reset after I create txn in a goroutine, before read call txn.Renew, after read call txn.Reset again. But some time, txn.Renew return error:
mdb_cursor_renew: invalid argument
So
- How to use these two funcs?
- Need I call cursor.Renew after txn.Renew?
So are you using a cursor in your read transactions? I'm not immediately sure why mdb_cursor_renew
is in that error message.
The order of txn operations sounds fine... Begin, Reset, Renew, Get, Reset, Renew, Get, Reset, Renew, ..., Abort. If cursors are not involved I believe that should work.
When you are using cursors you should make sure to call txn.Renew()
before calling cursor.Renew(txn)
-- make sure the transaction you are giving the cursor is "open". If you call those methods in reverse order you will probably get an error like the one you provided.
@bmatsuo after txn.Reset
and before txn.Renew
, may GC free this txn?
@zwb-ict no, the GC will not free the txn. As far as I know the primary benefit of reseting/renewing transactions is to reduce allocations and bookkeeping. It wouldn't be very useful if the GC destroyed the transaction between calls.
You should also make sure that txn.Abort() is called when you are done with the Txn object because the C library needs to clean up the transaction and do its final bookkeeping.
@bmatsuo this caused by open the same env in multi goroutines.