Contains object type to locking semantics bindings.
For a list of all members of this type, see LockingSemanticsBindings Members.
System.Object
LockingSemanticsBindings
LockingSemanticsBindings is used to bind locking semantics to object types per DataDomain in a Context. LockingSemanticsBindings are used by Context.Lock and Context.TryLock to determine the locking semantics to be used when locking persistent objects if not explicitly specified in the method call.
The LockingSemanticsBindings is also used for configure the delegation of the locks. When a lock operation is requested on the Context, the handling of the lock can be delegated on the context hierarchy to its base context. To attempt the delegation of a lock for a given type, the attemptDelegate has to be set to true. For the delegation to be successful, one of the base contexts has to accept the handling of the lock by setting the acceptDelegatedLock flag to true. If a context in the hierarchy does not delegate the lock handling and none of the contexts accepts it, then the delegation will fail and the lock will be handled by the context the operation was requested on.
When the Context is to be committed, the state of the locks should be checked, to determine if there are no lock violation. To specify whether to check the locks for the given type on the base contexts as well, the checkParentLock flag has to be set to true.
After a successful commit operation, the locks may or may not wanted to be released. This can be controlled by specifying a CommitArgs object for the Context.Commit method. This CommitArgs.LockMode property of this structure can be used to control the lock release mode. By default the context will release the locks held by itself only (LockCommitMode.ReleaseContext).
The configured locking behaviour can be overriden by requesting explicit locks on the context. Explicit locks will be handled by the context itself, ignoring the configuration. This can be achieved by passing a LockArgs structure to the Context.Lock method, and setting the LockArgs.ExplicitLock flag to true. Please note, that the Context.HasLocked and Context.Unlock operations are also checking the locks with the configured behaviour, so their behaviour are also has to be overriden by requesting an explicit operation in order to check/unlock an explicitly locked object.
LockingSemanticsBindings semanticsBindings = new LockingSemanticsBindings;
//Add a default binding
semanticsBindings.Add(typeof(object), OptimisticLockingSemantics.Value);
//Override the default binding for a specific DataDomain
semanticsBindings.Add(dataDomain1, typeof(object), PessimisticLockingSemantics.Value);
//Override the default binding for a specific type
semanticsBindings.Add(typeof(Person), PessimisticLockingSemantics.Value);
//override the default binding for a specific type in a specific DataDomain
semanticsBindings.Add(dataDomain1, typeof(Person), OptimisticLocking.Value;
//set the default lease timeout for pessmistic locking to 20 minutes
PessimisticLockDefaults defaultSettings = new PessimisticLockDefaults();
defaultSettings.LeaseTimeout = new TimeSpan(0,20,0);
semanticsBindings.SetDefaults(PessimisticLockingSemantics.Value, defaultSettings);
using(Context.Push(LocalContext.Create(semanticsBindings)))
{
Company company1 = (Company)otherDataDomain.Extent(typeof(Company))["Name={0}", "ACME"].ToObject();
// this will use optimistic locking
Context.Current.Lock(company1);
Company company2 = (Company)dataDomain1.Extent(typeof(Company))["Name={0}", "ACME"].ToObject();
// this will use pessimistic locking
Context.Current.Lock(company2);
Person person1 = (Person)otherDataDomain.Extent(typeof(Person))["Name=={0}", "Adam"].ToObject();
// this will use pessimistic locking
Context.Current.Lock(person1);
Person person2 = (Person)dataDomain1.Extent(typeof(Person))["Name=={0}", "Adam"].ToObject();
// this will use optimistic locking
Context.Current.Lock(person2);
Context.Rollback();
}
Example to setting up lock delegation configuration:
PessimisticLockDefaults defaults = new PessimisticLockDefaults();
defaults.LeaseTimeout = new TimeSpan(0,0,1);
bindings.SetDefaults(PessimisticLockingSemantics.Value, defaults);
LockingSemanticsBindings outerbindings = new LockingSemanticsBindings();
// set the default bindings to accept all the delegated locks.
outerbindings.Add(typeof(object), PessimisticLockingSemantics.Value, false, true, false);
// override the bindings for type 'Person' not to accept the delegated locks.
outerbindings.Add(typeof(Person), PessimisticLockingSemantics.Value, false, false, false);
// override the bindings for type 'Customer' which may be the subclass of Person, to accept the delegated locks.
outerbindings.Add(typeof(Customer), PessimisticLockingSemantics.Value, false, true, false);
outerbindings.SetDefaults(PessimisticLockingSemantics.Value, defaults);
Context outer = ShortRunningTransactionContext.Create(outerbindings);
using (Context.Push(outer))
{
LockingSemanticsBindings innerbindings = new LockingSemanticsBindings();
// set the default bindings to not to delegate any lock
innerbindings.Add(typeof(object), PessimisticLockingSemantics.Value, false, false, false);
// override the default bindings to delegate the locks for type person to the base
innerbindings.Add(typeof(Person), PessimisticLockingSemantics.Value, true, true, true);
innerbindings.SetDefaults(PessimisticLockingSemantics.Value, defaults);
// set the base context to 'outer', also pass the bindings
Context inner = ShortRunningTransactionContext.Create(outer, innerbindings);
using (Context.Push(inner))
{
// create some objects and commit them
Person person = (Person)domain.New(typeof(Person), 1, "Normal person");
Customer customer = (Customer)domain.New(typeof(Customer), 2, "Customer person");
Customer otherCustomer = (Customer)domain.New(typeof(Customer), 3, "Other Customer person");
Something something = (Something)domain.New(typeof(Something), 1);
Context.CommitCurrent();
// lock person, it will try to delegate it, but as the base context
// will not accept it, it will be locked in 'inner'
inner.Lock(person);
// lock customer, this time the lock will be delegated to the base
inner.Lock(customer);
// lock the other customer explicitly in the inner context:
inner.Lock(otherCustomer, new LockArgs(true));
// lock something, it will be locked in 'inner', as the default configuration
// for inner doesn't delegates the locks
inner.Lock(something);
// ... do something with the objects ...
// commit the transaction, but keep all the locks for furter operations
inner.Commit(new CommitArgs(LockCommitMode.Keep));
// ... do some more operations ...
// commit the transaction, and release the locks in current context
// (locks on person, something and otherCustomer).
inner.Commit(new CommitArgs(LockCommitMode.ReleaseContext));
// ... do some more operations, this time touch customer only ...
// commit the transaction, this time release the locks held by the base context as well:
inner.Commit(new CommitArgs(LockCommitMode.ReleaseAll));
}
}
Namespace: TechTalk.Genome.Locking
Assembly: TechTalk.Genome (in TechTalk.Genome.dll)
Version: 4.2.4.4
Editions: Professional, Evaluation, Express
Database Platforms: Microsoft SQL Server 2000, Microsoft SQL Server 2005, Orcale 9i Release 2, Oracle 10g Release 2
LockingSemanticsBindings Members | TechTalk.Genome.Locking Namespace | Context | LockServerBindings | ILockingSemantics | OptimisticLockingSemantics | PessimisticLockingSemantics | Context.Lock | Context.TryLock