Concurrency control

Posts   
 
    
Twiddlepin
User
Posts: 2
Joined: 19-Jan-2005
# Posted on: 19-Jan-2005 16:03:51   

I'm a new user of LLBLGen, and I'm testing / evaluating with a view to deploying it in our next project. In doing so, I'm trying to implement concurrency control on updates to an Entity, but I'm getting inconsistent results.

I've created a predicate to compare the database value of the field I'm changing with the dbValue value of that field in my in-memory Entity. I'm specifying that predicate when calling the Save() method on the Entity.

        
selectedJournal = New JPSDA.EntityClasses.JournalsEntity(CInt(e.CommandArgument))
Session("selectedJournal") = selectedJournal
...
selectedJournal = CType(Session("selectedJournal"), JPSDA.EntityClasses.JournalsEntity)
selectedJournal.Jnl_Description = txtDescription.Text

Dim concurrencyPredicate As New SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression
concurrencyPredicate.Add(JPSDA.FactoryClasses.PredicateFactory.CompareValue(JPSDA.JournalsFieldIndex.Jnl_Description, SD.LLBLGen.Pro.ORMSupportClasses.ComparisonOperator.Equal, selectedJournal.Fields(JPSDA.JournalsFieldIndex.Jnl_Description).DbValue))

selectedJournal.Save(concurrencyPredicate)

When testing by changing the value externally between loading the entity and calling the Save(), the Save() is nearly (!) always completing, which it shouldn't.

What appears to be happening is that when I change the value of the property on the Entity instance, its details are being reloaded from the database and so the dbValue value is then up to date, and the concurrency predicate doesn't fail as it should. Stepping through the generated code and referring to the documentation I see that when setting a property value the method SetNewFieldValue() method is called which ...

... will refetch the complete entity's fields from the database if necessary (i.e. the entity is outofsync.).

What does "outofsync" mean in this context and how can I stop it doing that refetch?

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 19-Jan-2005 17:24:26   

When an entity is saved, it is marked 'outofsync', which means the in-memory copy of the entity is not uptodate with the entity date in the database. This is to make sure an entity is refetched the next time you access it, so default values set by default constraints in the db are read.

So if you do: - create new entity - save it - create some predicate - alter some value in the table - save again you won't get the results you want.

However as soon as the entity is refetched from the db, it is not refetched again on the next property access, just the first time.

Looking at your code, it should work. Could you test for me if selectedJournal.Fields(JPSDA.JournalsFieldIndex.Jnl_Description).DbValue is indeed different than selectedJournal.Jnl_Description ?

Frans Bouma | Lead developer LLBLGen Pro
Twiddlepin
User
Posts: 2
Joined: 19-Jan-2005
# Posted on: 19-Jan-2005 18:57:13   

Otis wrote:

When an entity is saved, it is marked 'outofsync', which means the in-memory copy of the entity is not uptodate with the entity date in the database.

That's the answer. In my testing, I was fetching it, then calling Save(), and then altering the database externally. So when I called Save() again the Entity was "outofsync" and therefore forced to refetch when I changed one of its properties.

So what I've done now is to call Refetch() after a successful Save() (and then in this case refresh my session copy of the entity).

        If selectedJournal.Save(concurrencyPredicate) Then
            'Successful save
            selectedJournal.Refetch()
            Session("selectedJournal") = selectedJournal
        Else
            errConcurrency.IsValid = False
        End If

Many thanks for your quick and clear help sunglasses

But it leads me to another question ...

Are there any configurations for LLBL which include concurrency checking of updates in the generated code. Presumably, if the entity has dbValue for all attributes of the entity, this would be relatively wink easy.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 20-Jan-2005 10:21:29   

Twiddlepin wrote:

But it leads me to another question ...

Are there any configurations for LLBL which include concurrency checking of updates in the generated code. Presumably, if the entity has dbValue for all attributes of the entity, this would be relatively wink easy.

No, as concurrency is something almost every developer wants to do differently. So that's why LLBLGen Pro uses an interface: IConcurrencyPredicateFactory. By plugging an implementation of that interface into an entity, it is used by save and delete actions to produce predicates for concurrency control. This makes it possible for you to write your own concurrencyscheme without problems and you're not bound to a limited set of quircky concurrency systems. simple_smile

Frans Bouma | Lead developer LLBLGen Pro