This website is intended as archive for old content and forums.
Please visit http://opf3.codeplex.com for the project's new website.

Technical Support

FORUM TOPIC

Who, what tha..., why? How to set up Opf3 and keep it running smoothly. Search this Forum to find others who have driven down your road and have advice and tips to help you out (btw. we are helping too Happy).

RSS
POK CHAI GUAN
Posted on the 03/30/06 6:40 AM
Best Practices for Multi-users Clients/Server Application
Reply Quote
 Hi, Christian

In the Guidelines section of your Documentation, you shared some of your insight (Best Preactices) on the use of opf3 in various scenarios including one on ASP. I wonder you could similarly share with me your insight or recommended best practices regarding the use of opf3 in a multi-users clients/server environment as well?

For example, should I establish a single context during application initialisation and use it throughout the application or should I establish new context for every datastore access?

thanks & best regards
Pok

Christian Liensberger [Moderator]
Posted on the 03/30/06 7:27 AM
RE: Best Practices for Multi-users Clients/Server Application
Reply Quote
 Hi Pok,

working with Opf3 in a multi-user clients environment is quite easy:

The ObjectContext is not multithreading enabled, means you can't save/load/... with multiple threads on one ObjectContext instance without getting problems.

You need at least for each thread/client an ObjectContext. You could create an ObjectContextFactory that returns for each thread, client or on each call a new instance of the ObjectContext (I prefer the last option). If you return for each call a new instance your persistent objects should implement the ISelfContainingObject interface.

The ISelfContainingObject interface should be always implemented, when you use different ObjectContext instances for one persistent instance: for example, you load with one instance, save with another etc.

What does the interface do?
Well it tells Opf3 to save the ObjectInformation object into the persistent itself. The ObjectInfo object contains information about the state of the object (loaded, udpated, inserted, deleted, marked for deletion) and the concurrency information. If the interface is not implemented the object information is saved in the ObjectContext instance!

But attention: One thing you need to consider is the following szenario: you have implemented the ISelfContainingObject interface, and you load the persistent from one storage and try to save it in another storage. Since the state data is saved in the persistent itself, when trying to save, the second ObjectContext things the object has been loaded and does an update. That does not work! In that case you have to reset the state manually:

ObjectContext context1 = new ObjectContext(new AccessStorage("..."));
ObjectContext context2 = new ObjectContext(new MsSqlStorage("..."));

// Load a foo persistent. The persistent implements the
// ISelfContainingObject interface.
Foo foo = context1.GetObject<Foo>("ID = {0}", 1);

// Reset the object's state.
foo.ObjectInfo.ObjectState = ObjectStates.None;
// Does an update now.
context2.PersistChanges(foo);


But as long as you work on one physical database or you don't move objects from one database you are fine.

ConcurrencyManager
In a multi-user environment you need concurrency checks. Opf3 offers for that a concurrency manager. The concurrency manager is implemented as an interface. You may add you own if you want. Opf3 comes already with one that does check sums on the persistent objects.

When you do an update the Md5ConcurrencyManager (the one that comes with Opf3) reloads the object from the database and checks if the object has been altered by a third person, while you had it in memory. If that happened the manager fires a ConcurrencyException.

ObjectContext context = new ObjectContext(...);

// Configure Opf3 for a multi-user environment.
context.ConcurrencyManager = new Md5ConcurrencyManager();
// Done!


The next version of Opf3 includes also a concurrency manager working with timestamps.


More on this multi-user client server is found in here

I hope this helps. If you have further question, don't hesitate to write us again.

Christian

POK CHAI GUAN
Posted on the 03/30/06 7:51 AM
RE: Best Practices for Multi-users Clients/Server Application
Reply Quote
 Hi, Christian

First of all, thanks for your quick response and excellent answer and supports.

Further to your response,

1)... or on each call a new instance of the ObjectContext (I prefer the last option).
Question:- Could you provide a sample code on creating a new instance of the objectContext on each call?

2) The next version of Opf3 includes also a concurrency manager working with timestamps.
Question:- Any indicative date on the next release?



Christian Liensberger [Moderator]
Posted on the 03/30/06 7:58 AM
RE: Best Practices for Multi-users Clients/Server Application
Reply Quote
 

POK CHAI GUAN wrote:
Hi, Christian

First of all, thanks for your quick response and excellent answer and supports.

Further to your response,

1)... or on each call a new instance of the ObjectContext (I prefer the last option).
Question:- Could you provide a sample code on creating a new instance of the objectContext on each call?

2) The next version of Opf3 includes also a concurrency manager working with timestamps.
Question:- Any indicative date on the next release?

Here you go:

// Returns fully initialized instances of the ObjectContext.
public static class ObjectContextFactory
{
   // Returns a new fully initialized instance of the ObjectContext.
   public static ObjectContext GetObjectContext()   
   {   
      // Create a connection to the database.
      ObjectContext context = new ObjectContext(
         new AccessStorage(@"C:\", "db.mdb"));
      // Set a concurrency manager.
      context.ConcurrencyManager = new Md5ConcurrencyManager();

      return context;
   }
}



I can't say anything about the release of the next version. I can give you an internal test version if you like that. But you have to consider one thing: The TimeStampConcurrencyManager requires you to have an additional field in every database table. That field is used by Opf3 to store the timestamp (It's actually a guid that is stored as varchar there).

The TimeStampConcurrencyManager does not work with legacy databases. It is just an option if you create a new database from scratch.

If you want the internal test version, just use our support e-mail handle.

Christian

All times are in GMT.