Im working on integrating db4o into my project and I have some questions. I did read the manual and I tried out a few examples, but Im still not sure if I understood everything correctly. Please answer with yes/no (or other answers if there a questions which require this :-))
1.) Using ObjectContainer as a Singleton in an application is not recommended, because if different transactions work on the same object, there can be conflicts.
2.) So for concurrent transactions its recommended to use an embedded server.
3.) When using an embedded server (locally), you can open (and close) as much clients as you want, which have their own transaction and reference cache, so that they can work on the same objects. BUT - this is still not thread safe, because two clients might work on the same object, one client might change it and then the other won't update it.
4.) so - even if working with different clients, you need to make sure that the objects the clients work with are always up to date
5.) you can assure this with callbacks or explicit refreshing. but using callbacks would mean a lot of network traffic and explicit refreshing is complicated, because you really need to make sure when to update which object - so what would you recommend? and when would you refresh objects explicitly?
6.) as I try to write a DAO for db4o, I would implement methods for opening and closing the server and opening and closing the clients. I guess the server is only opened ONCE in an application, correct? (One Server per application?)
7.) Would you recommend lazy initialization? so that only the first time the server is needed, it is initialized.
8.) would you open a new client for every transaction?
9.) Assuming that I work with multiple transaction, but that they cant inflict each other, can I use one ObjectContainer for the whole project?
thank you for answering :-)
Depends on the application. Yes, each container has its own transaction and reference cache, so objects are shared. In a desktop or mobile application which does only one thing a time this can be the desired model. In a web application with multiple things going on at the same time is rarely the right model.
Yes. You can open a new session container with container.ext().openSession()
db4o has a 'read committed' isolation between object containers / transactions. A container only reads committed states from other transactions. But as you noticed, a container can see an outdated object, because he used his local cached version of the object. There's nothing much you can do.
Yes. db4o doesn't support you in this scenario.
Hmm, event with refreshing & stuff there no guarantee that you get a 100% consistent view on your data. You cannot reach the 'serialized' isolation level. The db4o consistence model just doesn't support that when multiple transactions are involved. If you race conditions are rare, then you might just 'ignore' the issue. It guess in many cases it's easier to try to deal / live / embrace the fact that db4o doesn't have a stronger isolation level. Stuff like 'refreshing' & 'refresh on event' only reduces the chances of such race-conditions, but cannot avoid them completely. When you really need a 100% correctnes, you need a database which supports 'serialized' isolation.
Yes, usually you have on db4o instance running and then multiple clients or session containers.
I wouldn't do lazy initialization if not absolutely necessary. When you need the database anyway, then just start it up. But anyway, that really depends on your application.
Also depends on your application. For example in a webapplication I would use a new session container per web-session. Anyway, every time you need a 'clean' state you should use a new object container. You shouldn't share a object container between different units of work. And don't share a object container across threads, unless you have some synchronization on top of it.
You can only have one transaction per object container. When you need more than one transaction at the same time, you need multiple containers anyway. When you have different tasks which are executed one after another, then you can use one container and the same transaction.