TransactionCache.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Transactions
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.ServiceModel;
  10. using System.ServiceModel.Channels;
  11. using System.ServiceModel.Security;
  12. using System.Threading;
  13. using System.Transactions;
  14. using System.Xml;
  15. //------------------------------------------------------------------------------------------
  16. // Transaction caches
  17. //------------------------------------------------------------------------------------------
  18. class WsatExtendedInformationCache : TransactionCache<Transaction, WsatExtendedInformation>
  19. {
  20. public static void Cache(Transaction tx, WsatExtendedInformation info)
  21. {
  22. WsatExtendedInformationCache entry = new WsatExtendedInformationCache();
  23. entry.AddEntry(tx, tx, info);
  24. }
  25. }
  26. class WsatIncomingTransactionCache : TransactionCache<string, Transaction>
  27. {
  28. public static void Cache(string identifier, Transaction tx)
  29. {
  30. WsatIncomingTransactionCache entry = new WsatIncomingTransactionCache();
  31. entry.AddEntry(tx, identifier, tx);
  32. }
  33. }
  34. abstract class TransactionCache<T, S>
  35. {
  36. static Dictionary<T, S> cache = new Dictionary<T, S>();
  37. static ReaderWriterLock cacheLock = new ReaderWriterLock();
  38. T key;
  39. protected void AddEntry(Transaction transaction, T key, S value)
  40. {
  41. this.key = key;
  42. if (Add(key, value))
  43. {
  44. transaction.TransactionCompleted += new TransactionCompletedEventHandler(OnTransactionCompleted);
  45. }
  46. }
  47. void OnTransactionCompleted(object sender, TransactionEventArgs e)
  48. {
  49. Remove(this.key);
  50. }
  51. static bool Add(T key, S value)
  52. {
  53. bool lockHeld = false;
  54. try
  55. {
  56. try { }
  57. finally
  58. {
  59. cacheLock.AcquireWriterLock(Timeout.Infinite);
  60. lockHeld = true;
  61. }
  62. if (!cache.ContainsKey(key))
  63. {
  64. cache.Add(key, value);
  65. return true;
  66. }
  67. }
  68. finally
  69. {
  70. if (lockHeld)
  71. {
  72. cacheLock.ReleaseWriterLock();
  73. }
  74. }
  75. return false;
  76. }
  77. static void Remove(T key)
  78. {
  79. bool lockHeld = false;
  80. try
  81. {
  82. try { }
  83. finally
  84. {
  85. cacheLock.AcquireWriterLock(Timeout.Infinite);
  86. lockHeld = true;
  87. }
  88. bool remove = cache.Remove(key);
  89. if (!(remove))
  90. {
  91. // tx processing requires failfast when state is inconsistent
  92. DiagnosticUtility.FailFast("TransactionCache: key must be present in transaction cache");
  93. }
  94. }
  95. finally
  96. {
  97. if (lockHeld)
  98. {
  99. cacheLock.ReleaseWriterLock();
  100. }
  101. }
  102. }
  103. public static bool Find(T key, out S value)
  104. {
  105. bool lockHeld = false;
  106. try
  107. {
  108. try { }
  109. finally
  110. {
  111. cacheLock.AcquireReaderLock(Timeout.Infinite);
  112. lockHeld = true;
  113. }
  114. if (cache.TryGetValue(key, out value))
  115. {
  116. return true;
  117. }
  118. }
  119. finally
  120. {
  121. if (lockHeld)
  122. {
  123. cacheLock.ReleaseReaderLock();
  124. }
  125. }
  126. return false;
  127. }
  128. }
  129. }