New Posts New Posts RSS Feed: Multiple concurrent save operations
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Multiple concurrent save operations

 Post Reply Post Reply
Author
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Topic: Multiple concurrent save operations
    Posted: 11-Oct-2012 at 2:08am
Hi,

We're developing a 'test player' that presents questions to the user awaits a response and then saves that response to the db.

It happens that when the user responds quickly to question after question, we get the error that the save operation failed because another was still in progress.

Is there a way to tell df to queue the operations and quietly handle the commits without throwing exceptions?

Thanks
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 11-Oct-2012 at 8:17am
No, there is not. One of the reasons Cocktail does not allow concurrent saves in a single EntityManager is if you have new entities and you do multiple saves, they all will attempt to insert the same records in the database and you end up with duplicates. You have to wait for the save to go through and let DF reconcile the cache once the save succeeds. If you keep modifying the cache while the save operation is still going on you risk inconsistencies.

If you want concurrent saves then you need to create a new EntityManager for each question, so you can save the answers concurrently without potential inconsistencies.


Edited by mgood - 11-Oct-2012 at 8:18am
Back to Top
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Posted: 16-Oct-2012 at 4:38am
And creating a new unitofwork will do just that?
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 16-Oct-2012 at 8:57am
Yes, provided you follow the advise given in the documention to ensure each UnitOfWork uses a new instance of the EntityManagerProvider in order to be sandboxed.
 
 
Each question should be it's own unit of work. I'm wondering, though, what does your application do if the user moves on to the next question and then the previous answer fails to save? Wouldn't you want to wait before letting the user move on to make sure the answer actually saves successfully?
Back to Top
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Posted: 16-Oct-2012 at 9:20am
We want to move on, because we are pretty sure the answer will be 'dumped' into a keyless (!) table without any issues. If an issue arises, it probably will be a connection issue, with which we will deal later, when we start thinking about offline scenarios where answers will be buffered till communications are restored.

It is more important that the user can progress to the next question and continue the test.

Thank you for your helpful responses so far.

Something like this should do it?
var uow = new TestUnitOfWork(new EntityManagerProvider<AdamMiloEntities>(), _testCache);

(The testcache analogous to IGlobalCache in TH, is something we need since we cache certain sets of data to (hopefully) improve performance and avoid async headaches).

Thanks again!



Edited by siko - 16-Oct-2012 at 9:26am
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 16-Oct-2012 at 10:12am
You want to handle sandboxing during dependency injection as is done in TempHire and illustrated here:
 
 
The import attribute ensures with the NonShared creation policy that MEF injects a new instance. This works in conjunction with a provider factory as outlined below, so that MEF can in fact create multiple instances of the EntityManagerProvider.
 
Back to Top
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Posted: 16-Oct-2012 at 11:38am
Nice work. Thanks.
Back to Top
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Posted: 24-Oct-2012 at 11:38pm
Originally posted by mgood

...
I'm wondering, though, what does your application do if the user moves on to the next question and then the previous answer fails to save? Wouldn't you want to wait before letting the user move on to make sure the answer actually saves successfully?
...
 
*blushes* ehm, I guess you're right about that after all...
We were on a, at first hidden, quest to defeat the fundamental nature of SL: Asynchrony. *blushes some more*.
 
In our attempts to have the best application responsiveness, we thought we could just cache everything and have the framework (devforce) do the async synchronization (...) for us. But even there we found out that while the records/entities were saved, they dissappeard from cache (we understand why, and it is logical!) ... so, waiting is essential and OperationResult's and IEnumerable<INotifyCompleted> are the constructs to apply.
 
The thought to make our own cache that is always available synchronously, will cause us issues down the line I'm sure and it is just not the type of code I want or need to write.
 
But there is still a thought in me that says: "Yes you can! Use two entitymanagers, one in which you read/update/create/delete, but is in disconnected state and one that actually is connected.  Have a background worker periodically find all the entities not in 'Unchanged' state, import those into the connected EM, set the state to Unchanged in the disconnected EM and execute commitasync on the connected EM." ... But it is probably not specific enough to reveal issues we will find there....
 
So, we'll wait in the mean time ;)
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 24-Oct-2012 at 11:48pm
Originally posted by siko

 
Have a background worker periodically find all the entities not in 'Unchanged' state, import those into the connected EM, set the state to Unchanged in the disconnected EM and execute commitasync on the connected EM." ... 

You can only safely use an EntityManager from the thread that created it. You'll get an exception if you try to perform certain operations from another thread. The EntityManager is not thread-safe. You can defeat the exception, but you should only do that if you know for sure what you are doing. 
Back to Top
siko View Drop Down
Newbie
Newbie
Avatar

Joined: 26-Mar-2012
Posts: 27
Post Options Post Options   Quote siko Quote  Post ReplyReply Direct Link To This Post Posted: 25-Oct-2012 at 12:30am
Hmm, yeah, multithreading ... nah, we'll wait for the callback ;)
 
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down