Jul
29
2011

TIP for XPO ThreadSafeDataLayer

User Rating: / 0
PoorBest 

When dealing with services or websites where many operations can be requested asynchronously from different threads, you must ensure that you use the ThreadSafeDataLayer.

The DX help document http://documentation.devexpress.com/#XPO/clsDevExpressXpoThreadSafeDataLayertopic does have a little Note which reads:

Prior to performing any operations with persistent objects in a data store using thread-safe data access layers, call the Session.CreateObjectTypeRecords method to obtain complete metadata information on the persistent objects.

Now the problem is, some XPO novices may run into issues, as per “XPO Best Practices” the Default Session should be null and therefore, this will mean that they will create a new Session using their newly created ThreadSafeDataLayer. The issue is here is that the ThreadSafeDataLayer requires all SchemaUpdates/ObjectType records to already be in place (due to the asynchronous ways the ThreadSafeDataLayer cannot safely ensure that if it did a UpdateSchema/CreateObjectTypeRecords that there isn’t already another thread requesting this)

So, what does this note from DX mean?

Basically you need to use a SimpleDataLayer first to ensure your database schema is valid and up to date. When I create a new DataStore during my service/application initialisation I have a pattern like this:

        ' Define assemblies that contain XPO objects used in this data store
        Dim DataAssemblies As New List(Of Reflection.Assembly)
        DataAssemblies.Add(GetType(Central.BaseObject).Assembly)
        DataAssemblies.Add(GetType(Data.Objects.BaseObject).Assembly)

        ' Define the datastore
        Dim ds As IDataStore = New InMemoryDataStore() ' using memory store just for an example
        ' other real examples to create a datastore, this can be anything such as Access, MySQL, SQLite, MSSQLCE etc.
        'ds = XpoDefault.GetConnectionProvider(MSSqlConnectionProvider.GetConnectionString("localhost", "myUsername", "myPassword", "testdb"), AutoCreateOption.DatabaseAndSchema, Nothing)
        'ds = MSSqlConnectionProvider.CreateProviderFromString("Data Source=localhost;Initial Catalog=testdb;User Id=myUsername;Password=myPassword;", AutoCreateOption.DatabaseAndSchema, Nothing)

        ' Ensure data schema is updated
        Using sdl As New SimpleDataLayer(ds)
            Using uow As New UnitOfWork(sdl)
                uow.CreateObjectTypeRecords(DataAssemblies.ToArray)
                uow.UpdateSchema(DataAssemblies.ToArray)
            End Using
        End Using

        'Create dictionary to tell ThreadSafeDataLayer what Classes will be persisted
        Dim AssDict As New Metadata.ReflectionDictionary()
        AssDict.CollectClassInfos(DataAssemblies.ToArray) ' Will iterate the assembly to find all IXPObject implementors
        Dim tsdl As New ThreadSafeDataLayer(AssDict, ds)

        'Now it is safe to use the ThreadSafeDataLayer
        Using uow As New UnitOfWork(tsdl)
            ' Do Something 
        End Using

 

This seems to be the safest way to ensure that during your service/application running that you won’t end up with SchemaUpdateRequired exceptions or other weird exceptions with Index’s etc.

Hope this helps

Add comment

Although I believe your free to say what you want, please don't abuse either myself or other peoples, be constructive.


Security code
Refresh

Latest Comments

My Twitter

Follow me on twitter