/// <summary> 
		/// Performs a pessimistic lock upgrade on a given entity, if needed. 
		/// </summary>
		/// <param name="entity">The entity for which to upgrade the lock.</param>
		/// <param name="entry">The entity's EntityEntry instance.</param>
		/// <param name="requestedLockMode">The lock mode being requested for locking. </param>
		/// <param name="source">The session which is the source of the event being processed.</param>
		protected virtual void UpgradeLock(object entity, EntityEntry entry, LockMode requestedLockMode, ISessionImplementor source)
		{
			if (requestedLockMode.GreaterThan(entry.LockMode))
			{
				// The user requested a "greater" (i.e. more restrictive) form of
				// pessimistic lock
				if (entry.Status != Status.Loaded)
				{
					throw new ObjectDeletedException("attempted to lock a deleted instance", entry.Id, entry.EntityName);
				}

				IEntityPersister persister = entry.Persister;

				if (log.IsDebugEnabled)
				{
					log.Debug(string.Format("locking {0} in mode: {1}", MessageHelper.InfoString(persister, entry.Id, source.Factory), requestedLockMode));
				}

				ISoftLock slock;
				CacheKey ck;
				if (persister.HasCache)
				{
					ck = new CacheKey(entry.Id, persister.IdentifierType, persister.RootEntityName, source.EntityMode, source.Factory);
					slock = persister.Cache.Lock(ck, entry.Version);
				}
				else
				{
					ck = null;
					slock = null;
				}

				try
				{
					if (persister.IsVersioned && requestedLockMode == LockMode.Force)
					{
						// todo : should we check the current isolation mode explicitly?
						object nextVersion = persister.ForceVersionIncrement(entry.Id, entry.Version, source);
						entry.ForceLocked(entity, nextVersion);
					}
					else
					{
						persister.Lock(entry.Id, entry.Version, entity, requestedLockMode, source);
					}
					entry.LockMode = requestedLockMode;
				}
				finally
				{
					// the database now holds a lock + the object is flushed from the cache,
					// so release the soft lock
					if (persister.HasCache)
					{
						persister.Cache.Release(ck, slock);
					}
				}
			}
		}
예제 #2
0
 public override ILockingStrategy GetLockingStrategy(ILockable lockable, LockMode lockMode)
 {
     if (lockMode.GreaterThan(LockMode.Read))
     {
         return(new UpdateLockingStrategy(lockable, lockMode));
     }
     else
     {
         return(new SelectLockingStrategy(lockable, lockMode));
     }
 }
예제 #3
0
        public override SqlString ApplyLocksToSql(SqlString sql, IDictionary <string, LockMode> aliasedLockModes, IDictionary <string, string[]> keyColumnNames)
        {
            // TODO:  merge additional lockoptions support in Dialect.applyLocksToSql

            var buffer     = new StringBuilder(sql.ToString());
            int correction = 0;

            foreach (KeyValuePair <string, LockMode> entry in aliasedLockModes)
            {
                LockMode mode = entry.Value;

                if (mode.GreaterThan(LockMode.Read))
                {
                    string alias = entry.Key;
                    int    start = -1;
                    int    end   = -1;

                    if (sql.EndsWith(" " + alias))
                    {
                        start = (sql.Length - alias.Length) + correction;
                        end   = start + alias.Length;
                    }
                    else
                    {
                        int position = sql.IndexOfCaseInsensitive(" " + alias + " ");

                        if (position <= -1)
                        {
                            position = sql.IndexOfCaseInsensitive(" " + alias + ",");
                        }

                        if (position > -1)
                        {
                            start = position + correction + 1;
                            end   = start + alias.Length;
                        }
                    }

                    if (start > -1)
                    {
                        string lockHint = AppendLockHint(mode, alias);
                        buffer.Remove(start, end - start + 1);
                        buffer.Insert(start, lockHint);
                        correction += (lockHint.Length - alias.Length);
                    }
                }
            }
            return(new SqlString(buffer.ToString()));
        }
		private bool NeedsLockHint(LockMode lockMode)
		{
			return lockMode.GreaterThan(LockMode.Read);
		}
		public override string AppendLockHint(LockMode lockMode, string tableName)
		{
			if (lockMode.GreaterThan(LockMode.Read))
				return tableName + " holdlock";
			
			return tableName;
		}
예제 #6
0
		protected bool NeedsLockHint(LockMode lockMode)
		{
			return lockMode.GreaterThan(LockMode.Read);
		}
예제 #7
0
 protected bool NeedsLockHint(LockMode lockMode)
 {
     return(lockMode.GreaterThan(LockMode.Read));
 }
예제 #8
0
 private bool NeedsLockHint(LockMode lockMode)
 {
     return(lockMode.GreaterThan(LockMode.Read));
 }
예제 #9
0
 /// <summary>
 /// Disable outer join fetching if this loader obtains an
 /// upgrade lock mode
 /// </summary>
 protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle)
 {
     return(lockMode.GreaterThan(LockMode.Read) ? false : base.IsJoinedFetchEnabled(type, config, cascadeStyle));
 }
예제 #10
0
 public override ILockingStrategy GetLockingStrategy(ILockable lockable, LockMode lockMode)
 {
     if (lockMode.GreaterThan(LockMode.Read))
     {
         return new UpdateLockingStrategy(lockable, lockMode);
     }
     else
     {
         return new SelectLockingStrategy(lockable, lockMode);
     }
 }
		private void UpgradeLock( object obj, EntityEntry entry, LockMode lockMode )
		{
			if( lockMode.GreaterThan( entry.LockMode ) )
			{
				if( entry.Status != Status.Loaded )
				{
					throw new ObjectDeletedException( "attempted to lock a deleted instance", entry.Id, obj.GetType() );
				}

				IClassPersister persister = entry.Persister;

				if( log.IsDebugEnabled )
				{
					log.Debug( "locking " + MessageHelper.InfoString( persister, entry.Id ) + " in mode: " + lockMode );
				}

				ISoftLock myLock = null;
				if( persister.HasCache )
				{
					myLock = persister.Cache.Lock( entry.Id, entry.Version );
				}
				try
				{
					persister.Lock( entry.Id, entry.Version, obj, lockMode, this );
					entry.LockMode = lockMode;
				}
				finally
				{
					// the database now holds a lock + the object is flushed from the cache,
					// so release the soft lock
					if( persister.HasCache )
					{
						persister.Cache.Release( entry.Id, myLock );
					}
				}
			}
		}