The answer depends on what you're trying to do.
As I understand it, your process is something like:
- get a lot of data
- modify that data
- create a lot more data
- save it all in a single transaction
You are suggesting that saving it all could take a long time. Is that because the database takes a long time to do the work? Or because you think it will take a long time to both transmit the data from the client to the server and perform the save.
If you think the big hangup is moving data from client to server, is it possible that some of the data can be created/acquired and modified in the middle tier? We see that with audit records for example. I save ten objects each of which kicks out an average of 5 audit records. I don't want those audit records on the client and I certainly don't want to transmit them over a slow connection. But I do need to create them and include them in the transaction. This kind of thing is easily done in the Business Object Server execution space.
Now when you do the work in the BOS, the work of each client request is done on its own thread. Therefore, the save process within the BOS is inherently an async save.
If the database takes a long time to process the save, you may have to worry about a timeout between the database and the BOS. Are you really taxing the database with your save size? Perhaps we need to look at batch update or some similar kind of exceptional save approach; you will want to resort to this expedient only when necessary as it introduces complexity ... but it's there if you need it.
[Aside: I'm describing performance tuning techniques that you should draw upon only when you have measured performance and determined that it is unacceptable. Otherwise, we're just introducing complexity that you will have to understand and maintain. I'm sure you know this but it is always worth repeating.]
As I said at the top, you can perform a client side async save. That isn't something that comes right out of the DevForce box but it isn't terribly difficult to do (I'll give you a rough outline in a second).
What alarms me is the notion that the user can continue working while the data are being saved. What are they working on? Is it the same data that you're saving on a different thread. That is likely to cause concurrency problems later when they try to save their changes; you can resolve these but it could be tricky.
Let's suppose that your client side save process was taking care of a basket of work. Once the saving starts, the client turns to a completely new basket of work. The old basket is old news. How might I proceed?
In rough, the whole process looks like this:
- I'll assume that you have a working PersistenceManager (PM) with your changes to save
- Instantiate an instance of your "BackgroundSaver" class
- That BackgroundSaver has a "GetChanges()" method. You can give it the working PM or maybe you cherry pick the objects to save and pass that too it.
- The BackgroundSaver internally creates a new, private PM and copies the objects to save. This in-memory copy takes no perceptible time; there's a single PM method to perform that copy today.
- Remove the objects you're saving from the old PM (because you're moving on to a new basket, right?).
- Tell the BackgroundSaver to execute.
It acquires a thread from the ThreadPool and executes the PM.Save() method on its private PM on the background thread
- Add your own callback method to this mix
We needed to copy the data to an isolated PM in order to make sure no other thread has access to the data we're saving. Otherwise there would be memory concurrency problems that you definitely never want to have to debug. Since only the BackgroundSaver has access to its private PM, we're safe.
What if the background save fails? You'll have to capture the exception information in background and report it in the call back. Now, when the method returns reporting the problem, you have to figure out what to do. This is not that much different from how you handle a synchronous save failure. But it is a little different because the user thought he moved on ... and your program is suddenly going to be saying "hey, excuse me but, you know that save from a few seconds ago? Well ... there's been a problem."
That, in my mind, is how it gets tricky.
Hope this helps