Next: Performance Tips, Previous: Repository Migration, Up: Tutorial
Sleepycat plays well with threads and processes. The store controller
is thread-safe by default, that is, can be shared amongst threads.
This is set by the :thread
key. Transactions may not be shared
amongst threads except serially. One thing which is NOT thread and
process safe is recovery, which should be run when no one is else is
talking to the database environment. Consult the Sleepycat docs for
more information.
Elephant uses some specials to hold parameters and buffers. If you're
using a natively threaded lisp, you can initialize these specials to
thread-local storage by using the run-elephant-thread
function,
assuming your lisp creates thread-local storage for let-bound
specials. (This functionality is currently broken)
Persisting ordinary aggregate types (e.g. NOT persistent classes or btrees) suffers from something called "merge-conflicts." Since updating one value of an aggregate object requires the entire object to be written to the database, in heavily threaded situations you may overwrite changes another thread or process has committed. This is not protected by transactions!
Consider two processes operating on the same cons:
-----start---read--update-car--write--commit----------------
-start------read--update-cdr-----------------write--commit--
Although the first process successfully committed its transaction, its work (writing to the car) will be erased by the second transaction (which writes both the car and cdr.)
Persistent classes and persistent collections do not suffer from merge-conflicts, since each slot / entry is a separate database entry.