Ignore:
Timestamp:
01/15/09 15:04:50 (12 years ago)
Author:
svonolfe
Message:

Further improved locking mechanism (avoid race conditions, performance) (#372)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Hive.Server.ADODataAccess/DataAdapterBase.cs

    r1131 r1134  
    2626using System.Text;
    2727using HeuristicLab.Hive.Contracts.BusinessObjects;
    28 using System.Runtime.CompilerServices;
     28using System.Threading;
    2929
    3030namespace HeuristicLab.Hive.Server.ADODataAccess {
     
    3333    where RowT : System.Data.DataRow
    3434    where ObjT : IHiveObject, new() {
     35
     36    private static Mutex lockersMutex =
     37      new Mutex();
     38
     39    private static IDictionary<long, Mutex> lockers =
     40      new Dictionary<long, Mutex>();
     41
     42    private static IDictionary<long, int> lockCount =
     43      new Dictionary<long, int>();
     44
     45    protected void LockRow(long id) {
     46      Mutex rowLock = null;
     47
     48      /////begin critical section////
     49      lockersMutex.WaitOne();
     50
     51      if (!lockers.ContainsKey(id)) {
     52        lockers[id] = new Mutex();
     53        lockCount[id] = 0;
     54      }
     55      rowLock = lockers[id];
     56      lockCount[id]++;
     57     
     58      lockersMutex.ReleaseMutex();
     59      /////end critical section////
     60
     61      rowLock.WaitOne();
     62    }
     63
     64    protected void UnlockRow(long id) {
     65      Mutex rowLock = lockers[id];
     66      rowLock.ReleaseMutex();
     67
     68      /////begin critical section////
     69      lockersMutex.WaitOne();
     70
     71      lockCount[id]--;
     72      if (lockCount[id] == 0)
     73        lockers.Remove(id);
     74
     75      lockersMutex.ReleaseMutex();
     76      /////end critical section////
     77    }
     78   
    3579    protected AdapterT Adapter {
    3680      get {
     
    4488    protected abstract ObjT ConvertRow(RowT row, ObjT obj);
    4589
    46     [MethodImpl(MethodImplOptions.Synchronized)]
    4790    protected abstract RowT InsertNewRow(ObjT obj);
    4891
    49     [MethodImpl(MethodImplOptions.Synchronized)]
    5092    protected abstract void UpdateRow(RowT row);
    5193
     
    119161    }
    120162
    121     [MethodImpl(MethodImplOptions.Synchronized)]
    122163    public virtual void Update(ObjT obj) {
    123164      if (obj != null) {
     
    127168        if (row == null) {
    128169          row = InsertNewRow(obj);
     170          UpdateRow(row);
    129171        }
    130172
     173        obj.Id = (long)row[row.Table.PrimaryKey[0]];
     174        LockRow(obj.Id);
     175
    131176        ConvertObj(obj, row);
    132 
    133177        UpdateRow(row);
    134178
    135         obj.Id = (long)row[row.Table.PrimaryKey[0]];
     179        UnlockRow(obj.Id);
    136180      }
    137181    }
     
    149193    }
    150194
    151     [MethodImpl(MethodImplOptions.Synchronized)]
    152195    public virtual bool Delete(ObjT obj) {
     196      bool success = false;
     197     
    153198      if (obj != null) {
     199        LockRow(obj.Id);
     200
    154201        RowT row =
    155202          GetRowById(obj.Id);
     
    159206          UpdateRow(row);
    160207
    161           return true;
     208          success = true;
    162209        }
    163       }
    164 
    165       return false;
     210
     211        UnlockRow(obj.Id);
     212      }
     213
     214      return success;
    166215    }
    167216  }
Note: See TracChangeset for help on using the changeset viewer.