-
-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
invalid reuse of reader locktable slot #7
Comments
http://www.lmdb.tech/doc/starting.html
So making multiple |
Hi. Been pulling my hair until thought of checking the issues. This may still be a problem and IMO at least a note in the docs may help others. Easiest way to reproduce is something like this code (as you mentioned at the beginning): (let [conn (store/connect "bob")]
(let [conn (store/connect "bob")]
(store/transact! conn [{:foo/boo "boo"}])
(store/close conn))
(store/transact! conn [{:foo/baz "baz"}])
(store/close conn)) While one is unlikely to write this by hand, the following is a typical way to manage resources: (store/with [conn "bob"]
(store/with [conn "bob"]
(store/transact! conn [{:foo/boo "boo"}]))
(store/transact! conn [{:foo/baz "baz"}])) and will roughly expand into the first snippet. In fact even these macros are likely to occur in some function calls: (store/with [conn "bob"]
(perform-query that calls store/with itself)
... other queries and transactions) With few databases one can have a service that simply holds on to connections. With lots of them however you need to manage resources somehow. Argument can be made that it isn't Datalevin's place to deal with it, and I think that's fair. People may choose to do their own connection pooling or ref counting or smth, but they need to know they have to do it. Another option is to provide some lower level API to LMDB "environment" but I know nothing about LMDB to make reasonable suggestions. |
Thank you for mentioning this. I have updated the doc string and exception message to make it more clear.
|
Thank you. Re (defmacro with
""
{:style/indent [1 [[:defn]] :form]}
[[id conn] & body]
`(let [conn# ~conn
~id (connect conn#)]
(let [res# (do ~@body)
forced# (if (coll? res#) (doall res#) res#)]
;; Only close a connection that we open here. Connection established outside "with" and passed
;; in as an argument should remain opened.
(when-not (d/conn? conn#)
;; only close if still opened
(when (d/conn? ~id)
(d/close ~id)))
forced#))) issue I wanted to bring up had to do with someone, like me, writing something similar to the above thinking that you could open and close connections at will, when in fact semantically managing connections as resource is not straightforward with limitations and requirements imposed by LMDB implementation. |
Thank you for the clarification. However, I don't think Datalevin or LMDB is special in anyway compared with any other stateful database. It might be sufficient to tell people that Datalevin should be managed like any other stateful resources and give recommendation on what to use, i.e. a component like life cycle management tool that is commonly used for these use cases. I would submit that only a very small minority of Clojure users would think to write their own macros to do this kind of things. If they can write their own macro to manage a database connection, it is not that hard to implement something simple to reuse the connections. On the other hand, Datalevin can probably provide a |
Release 0.3.9 added |
Keep an old connection, use a new connection to transact, close the db. Try query on old connection, this error appears. Run the query second time, "transaction has not been reset" is thrown.
[Update] This is an expected behavior. See below.
The text was updated successfully, but these errors were encountered: