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/CachedDataAdapter.cs

    r1131 r1134  
    2525using System.Text;
    2626using HeuristicLab.Hive.Contracts.BusinessObjects;
    27 using System.Runtime.CompilerServices;
    2827using System.Data;
     28using System.Threading;
    2929
    3030namespace HeuristicLab.Hive.Server.ADODataAccess {
     
    4141    private static bool cacheFilled = false;
    4242
     43    private static ReaderWriterLock cacheLock =
     44      new ReaderWriterLock();
     45
    4346    protected DataTable dataTable =
    4447      new DataTable();
     
    4750      new List<ICachedDataAdapter>();
    4851
    49     [MethodImpl(MethodImplOptions.Synchronized)]
    5052    protected CachedDataAdapter() {
     53      cacheLock.AcquireWriterLock(Timeout.Infinite);
     54
    5155      if (!cacheFilled) {
    5256        FillCache();
     
    5458      }
    5559
     60      cacheLock.ReleaseWriterLock();
     61
    5662      ServiceLocator.GetTransactionManager().OnUpdate +=
    5763        new EventHandler(CachedDataAdapter_OnUpdate);
     
    6066    protected virtual RowT FindSingleRow(Selector dbSelector,
    6167      Selector cacheSelector) {
     68      cacheLock.AcquireReaderLock(Timeout.Infinite);
     69     
    6270      RowT row =
    6371         FindSingleRow(cacheSelector);
     
    6977      }
    7078
     79      cacheLock.ReleaseReaderLock();
     80
    7181      return row;
    7282    }
     
    7484    protected virtual IEnumerable<RowT> FindMultipleRows(Selector dbSelector,
    7585        Selector cacheSelector) {
     86      cacheLock.AcquireReaderLock(Timeout.Infinite);
     87
    7688      IList<RowT> result =
    7789         new List<RowT>(cacheSelector());
     
    8597        }
    8698      }
     99
     100      cacheLock.ReleaseReaderLock();
    87101
    88102      return result;
     
    105119    protected virtual ICollection<ObjT> FindMultiple(Selector dbSelector,
    106120      Selector cacheSelector) {
     121      cacheLock.AcquireReaderLock(Timeout.Infinite);
     122
    107123      ICollection<ObjT> result =
    108124        FindMultiple(cacheSelector);
     
    110126      ICollection<ObjT> resultDb =
    111127        FindMultiple(dbSelector);
     128
     129      cacheLock.ReleaseReaderLock();
    112130
    113131      foreach (ObjT obj in resultDb) {
     
    119137    }
    120138
    121     [MethodImpl(MethodImplOptions.Synchronized)]
    122139    protected abstract RowT InsertNewRowInCache(ObjT obj);
    123140
    124     [MethodImpl(MethodImplOptions.Synchronized)]
    125141    protected abstract void FillCache();
    126142
    127     [MethodImpl(MethodImplOptions.Synchronized)]
    128143    public abstract void SyncWithDb();
    129144
    130     [MethodImpl(MethodImplOptions.Synchronized)]
    131145    protected abstract bool PutInCache(ObjT obj);
    132146
    133147    protected abstract RowT FindCachedById(long id);
    134148
    135     [MethodImpl(MethodImplOptions.Synchronized)]
    136149    void CachedDataAdapter_OnUpdate(object sender, EventArgs e) {
    137150      foreach (ICachedDataAdapter parent in this.parentAdapters) {
     
    140153
    141154      this.SyncWithDb();
    142     }
    143 
    144     [MethodImpl(MethodImplOptions.Synchronized)]
    145     protected virtual void RemoveRowFromCache(RowT row) {
    146       cache.Rows.Remove(row);
    147155    }
    148156
     
    167175    }
    168176
    169     [MethodImpl(MethodImplOptions.Synchronized)]
     177    private void AddToCache(RowT row) {
     178      cacheLock.AcquireWriterLock(Timeout.Infinite);
     179
     180      cache.ImportRow(row);
     181      row.Table.Rows.Remove(row);
     182
     183      cacheLock.ReleaseWriterLock();
     184    }
     185
     186    private RowT AddToCache(ObjT obj) {
     187      cacheLock.AcquireWriterLock(Timeout.Infinite);
     188
     189      RowT row =  InsertNewRowInCache(obj);
     190
     191      cacheLock.ReleaseWriterLock();
     192
     193      return row;
     194    }
     195
     196    private void RemoveRowFromCache(RowT row) {
     197      cacheLock.AcquireWriterLock(Timeout.Infinite);
     198
     199      dataTable.ImportRow(row);
     200      cache.Rows.Remove(row);
     201
     202      cacheLock.ReleaseWriterLock();
     203
     204      UpdateRow(row);
     205    }
     206
    170207    public override void Update(ObjT obj) {
    171208      if (obj != null) {
     
    175212        if (row == null) {
    176213          if (PutInCache(obj)) {
    177             row = InsertNewRowInCache(obj);
     214            row = AddToCache(obj);
    178215          } else {
    179216            row = InsertNewRow(obj);
     
    184221
    185222        obj.Id = (long)row[row.Table.PrimaryKey[0]];
     223        LockRow(obj.Id);
    186224
    187225        ConvertObj(obj, row);
     
    191229
    192230        if (IsCached(row) &&
    193             !PutInCache(obj)) {
    194           //remove from cache
    195           dataTable.ImportRow(row);
     231            !PutInCache(obj)) {         
    196232          RemoveRowFromCache(row);
    197 
    198           UpdateRow(row);
    199233        } else if (!IsCached(row) &&
    200234          PutInCache(obj)) {
    201           //add to cache
    202           cache.ImportRow(row);
    203           row.Table.Rows.Remove(row);
    204         }
     235          AddToCache(row);
     236        }
     237
     238        UnlockRow(obj.Id);
    205239      }
    206240    }
Note: See TracChangeset for help on using the changeset viewer.