Thanks. I also have a search in the previous discussions and the following is probably the solution to my question.

https://www.openldap.org/lists/openldap-technical/201409/msg00077.html

Quoting from the above -

>    Before starting any other threads:
>       Create the environment.
>       Open a transaction.
>       Open all DBI handles the app will need.
>       Commit the transaction.

May I confirm my understanding that, after the above steps, each thread created for accessing the database in the same process should :

1. Open a transaction in the same environment
2. Directly use the persisted DBI handles (saved before creating the threads) for read / write without calling mdb_dbi_open
3. Commit / abort the transaction,

regardless of whether the DBI handle is used for read / write? 

Also, in respect of the initial transaction for opening the DBI handles, is a read-only transaction sufficient even if the database it opened would be written to in subsequent transactions, since the initial transaction itself would not be writing to the database?

Thanks a lot.

- H Law

2015-04-03 2:54 GMT+08:00 Howard Chu <hyc@symas.com>:
>
> hlaw wrote:
>>
>> Thank you!
>>
>> It appears that mdb_dbi_open() must be called before any read / write
>> access to a database in a transaction,
>
>
> True.
>
>> and all read / write have to be
>> done in a transaction?
>
>
> True.
>
>> If this is the case, is it correct that due to
>> the concurrency restriction above, there is essentially no concurrent
>> access (including read and write) to the same database in a
>> multi-threaded process,
>
>
> False.
>
>> since a database is available to one transaction
>> in a time?
>
>
> False. Reread the mdb_dbi_open doc. http://symas.com/mdb/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a
>
>>
>> 2015-03-30 19:52 GMT+08:00 Hallvard Breien Furuseth
>> <h.b.furuseth@usit.uio.no <mailto:h.b.furuseth@usit.uio.no>>:
>>
>>     You're abusing mdb_dbi_open().  Its doc says:
>>
>>        "This function must not be called from multiple concurrent
>>        transactions in the same process. A transaction that uses this
>>        function must finish (either commit or abort) before any other
>>        transaction in the process may use this function."
>>
>>     That text could have stood out a bit better in the doc:-(
>>
>>     The error is simple for lmdb to try to catch, though without
>>     locking it cannot guarantee to catch it.  Try this patch:
>>     <http://folk.uio.no/hbf/__OpenLDAP/mdb.serial-open.diff
>>     <http://folk.uio.no/hbf/OpenLDAP/mdb.serial-open.diff>>
>>
>>     (Howard, this is branch "mdb/serial-open" in my UiO repo.)
>>     Not sure if it should do more than this.  E.g. attack mdb_drop
>>     too.  Maybe set MDB_TXN_ERROR since a program with broken
>>     threading can break the DB.
>>
>>     --
>>     Hallvard
>>
>>
>
>
> --
>   -- Howard Chu
>   CTO, Symas Corp.           http://www.symas.com
>   Director, Highland Sun     http://highlandsun.com/hyc/
>   Chief Architect, OpenLDAP  http://www.openldap.org/project/