Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.LINQDataAccess/3.3/ContextFactory.cs @ 4120

Last change on this file since 4120 was 4120, checked in by cneumuel, 14 years ago

further improvement and stabilisation of HiveExperiment (#1115)

File size: 4.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Hive.Server.DataAccess;
6using System.Collections;
7using System.Data.Linq;
8using System.Transactions;
9using HeuristicLab.PluginInfrastructure;
10using HeuristicLab.Hive.Contracts;
11using HeuristicLab.Tracing;
12using System.Threading;
13
14
15namespace HeuristicLab.Hive.Server.LINQDataAccess {
16  /// <summary>
17  /// This class handles creates one Context for each Thread which asks for one.
18  /// If one Thread calls GetContext several times, it always gets the same Context object.
19  /// A context object is removed from the cache when it is disposed.
20  ///
21  /// Every context has a DB-Transaction over its livetime. After using the context object
22  /// it has to be disposed in order to finish the corresponding transaction.
23  /// </summary>
24  class ContextFactory : IContextFactory {
25    private static object locker = new object();
26    private static IDictionary<int, HiveDataContext> contexts = new Dictionary<int, HiveDataContext>();
27    private static IDictionary<int, TransactionScope> transactions = new Dictionary<int, TransactionScope>();
28
29    private static IContextFactory instance = null;
30    public static IContextFactory Instance {
31      get {
32        if (instance == null)
33          instance = new ContextFactory();
34        return instance;
35      }
36    }
37
38    #region IContextManager Members
39
40    public IDisposable GetContext() {
41      return GetContext(true);
42    }
43
44    public IDisposable GetContext(bool withTransaction) {
45      lock (locker) {
46        Logger.Debug("opening transaction");
47        int threadId = Thread.CurrentThread.ManagedThreadId;
48
49        if (contexts.ContainsKey(threadId)) {
50          throw new DataAccessException("Context for this Thread already defined");
51        }
52
53        Logger.Debug("creating context");
54        DisposableHiveDataContext context = CreateContext();
55        context.OnDisposing += new EventHandler(context_OnDisposing);
56        contexts.Add(threadId, context);
57
58        if (withTransaction) {
59          TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = ApplicationConstants.ISOLATION_LEVEL_SCOPE });
60          Logger.Debug("creating  transaction");
61
62          transactions.Add(threadId, transaction);
63        }
64        return context;
65      }
66    }
67
68    private static DisposableHiveDataContext CreateContext() {
69      return new DisposableHiveDataContext("Data Source=127.0.0.1;Initial Catalog=HeuristicLab.Hive;Integrated Security=SSPI");
70    }
71
72    void context_OnDisposing(object sender, EventArgs e) {
73      RemoveContext();
74      RemoveAndCompleteTransaction();
75    }
76
77    public void RollbackTransaction() {
78      Logger.Debug("rolling back transaction");
79      int threadId = Thread.CurrentThread.ManagedThreadId;
80
81      TransactionScope transaction = transactions[threadId];
82      transaction.Dispose();
83    }
84
85    public void RemoveContext() {
86      lock (locker) {
87        Logger.Debug("removing context");
88        int threadId = Thread.CurrentThread.ManagedThreadId;
89
90        contexts.Remove(threadId);
91        // context gets disposed implicitly, when it is used as IDisposable
92      }
93    }
94
95    public void RemoveAndCompleteTransaction() {
96      lock (locker) {
97        Logger.Debug("completing transaction");
98        int threadId = Thread.CurrentThread.ManagedThreadId;
99
100        // context does not always have an associated transaction
101        if (transactions.ContainsKey(threadId)) {
102          transactions[threadId].Complete();
103          transactions[threadId].Dispose();
104          transactions.Remove(threadId);
105        }
106      }
107    }
108
109    public DataContext CurrentContext {
110      get {
111        int threadId = Thread.CurrentThread.ManagedThreadId;
112        if (contexts.ContainsKey(threadId)) {
113          return contexts[threadId];
114        } else {
115          return null;
116        }
117      }
118    }
119
120    #endregion
121  }
122
123  /// <summary>
124  /// Offers an event when it gets disposed
125  /// </summary>
126  class DisposableHiveDataContext : HiveDataContext {
127
128    public DisposableHiveDataContext(string connection) : base(connection) { }
129
130    protected override void Dispose(bool disposing) {
131      base.Dispose(disposing);
132      if (OnDisposing != null)
133        OnDisposing(this, new EventArgs());
134    }
135
136    public event EventHandler OnDisposing;
137  }
138}
Note: See TracBrowser for help on using the repository browser.