/ToMigrate/Raven.Tests.Issues/RavenDB_1539.cs

https://github.com/fitzchak/ravendb · C# · 255 lines · 210 code · 45 blank · 0 comment · 6 complexity · 345cf432f708ad17c50e937d8871c911 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Transactions;
  7. using Raven.Client;
  8. using Raven.Client.Document;
  9. using Raven.Client.Util;
  10. using Raven.Tests.Common;
  11. using Raven.Tests.Helpers;
  12. using Xunit;
  13. namespace Raven.Tests.Issues
  14. {
  15. public class RavenDB_1539 : RavenTestBase
  16. {
  17. public class TestDoc
  18. {
  19. public string Id { get; set; }
  20. public string Data { get; set; }
  21. }
  22. [Fact]
  23. public void Several_SaveChanges_for_the_same_document_in_single_transaction_and_the_same_session_should_work()
  24. {
  25. using (var documentStore = NewRemoteDocumentStore(runInMemory: false, requestedStorage: "esent"))
  26. using (var session = documentStore.OpenSession())
  27. {
  28. if(documentStore.DatabaseCommands.GetStatistics().SupportsDtc == false)
  29. return;
  30. session.Advanced.UseOptimisticConcurrency = true;
  31. session.Advanced.AllowNonAuthoritativeInformation = false;
  32. using (var transaction = new TransactionScope())
  33. {
  34. var newDoc = new TestDoc { Data = "Foo" };
  35. session.Store(newDoc);
  36. session.SaveChanges();
  37. newDoc.Data = "Bar";
  38. session.SaveChanges();
  39. newDoc.Data = "Foo-Bar!";
  40. Assert.DoesNotThrow(() => session.SaveChanges());//should not throw concurrency exception
  41. transaction.Complete();
  42. }
  43. }
  44. }
  45. [Fact]
  46. public void Several_SaveChanges_for_the_same_document_in_single_transaction_should_allow_commit_without_concurrency_exception()
  47. {
  48. using (var documentStore = NewRemoteDocumentStore(runInMemory: false, requestedStorage: "esent"))
  49. using (var session = documentStore.OpenSession())
  50. {
  51. if (documentStore.DatabaseCommands.GetStatistics().SupportsDtc == false)
  52. return;
  53. session.Advanced.UseOptimisticConcurrency = true;
  54. session.Advanced.AllowNonAuthoritativeInformation = false;
  55. Assert.DoesNotThrow(() =>
  56. {
  57. using (var transaction = new TransactionScope())
  58. {
  59. var newDoc = new TestDoc { Data = "Foo" };
  60. session.Store(newDoc);
  61. session.SaveChanges();
  62. newDoc.Data = "Bar";
  63. session.SaveChanges();
  64. transaction.Complete();
  65. }
  66. });
  67. }
  68. }
  69. [Fact]
  70. public void StoreAndSaveThenUpdateNewDocumentInsideTransactionSucceedsUsingSession()
  71. {
  72. var input = GenerateEditable();
  73. using (var documentStore = NewRemoteDocumentStore(runInMemory: false, requestedStorage: "voron"))
  74. using (var session = documentStore.OpenSession())
  75. {
  76. if (documentStore.DatabaseCommands.GetStatistics().SupportsDtc == false)
  77. return;
  78. session.Advanced.UseOptimisticConcurrency = true;
  79. session.Advanced.AllowNonAuthoritativeInformation = false;
  80. using (var transaction = new TransactionScope())
  81. {
  82. var studentIds = new List<string>();
  83. var students = new List<Student>();
  84. input.Students.ForEach(x =>
  85. {
  86. var updatedStudent = new Student
  87. {
  88. Name = x.Name,
  89. Email = x.Email,
  90. Id = BaseIdentity<Student>.IdTemplate()
  91. };
  92. session.Store(updatedStudent);
  93. session.SaveChanges();
  94. updatedStudent.LastUpdatedBy = "bob";
  95. studentIds.Add(updatedStudent.Id);
  96. students.Add(updatedStudent);
  97. });
  98. var updatedCourse = new Course
  99. {
  100. Name = input.Course.Name,
  101. Students = studentIds,
  102. LastUpdatedBy = "bob"
  103. };
  104. session.Store(updatedCourse);
  105. session.SaveChanges();
  106. students.ForEach(x =>
  107. {
  108. x.CourseId = updatedCourse.Id;
  109. });
  110. Assert.DoesNotThrow(()=>session.SaveChanges());
  111. transaction.Complete();
  112. }
  113. }
  114. }
  115. private static Editable GenerateEditable()
  116. {
  117. return new Editable()
  118. {
  119. Course = new EditableCourse
  120. {
  121. Name = "Biology 101",
  122. },
  123. Students = new List<EditableStudent>
  124. {
  125. new EditableStudent
  126. {
  127. Name = "Bob Builder1",
  128. Email = "support@hibernatingrhinos1.com"
  129. },
  130. new EditableStudent
  131. {
  132. Name = "Bob Builder2",
  133. Email = "support@hibernatingrhinos2.com"
  134. },
  135. }
  136. };
  137. }
  138. public interface IBase
  139. {
  140. bool Deleted { get; set; }
  141. DateTime LastUpdated { get; set; }
  142. string LastUpdatedBy { get; set; }
  143. }
  144. public interface IBase<T> : IBase
  145. {
  146. T Id { get; set; }
  147. }
  148. public interface IBaseIdentity : IBase<string>
  149. {
  150. }
  151. public abstract class Base<T>
  152. {
  153. public T Id { get; set; }
  154. }
  155. public abstract class BaseIdentity<T> : Base<string>, IBaseIdentity
  156. where T : class
  157. {
  158. private static readonly string Name = Inflector.Pluralize(typeof(T).Name).ToLower();
  159. protected BaseIdentity()
  160. {
  161. Id = string.Format("{0}/", Name);
  162. }
  163. public DateTime LastUpdated { get; set; }
  164. public string LastUpdatedBy { get; set; }
  165. public static string AsId(int index)
  166. {
  167. return string.Format("{0}/{1}", Name, index);
  168. }
  169. public static string IdTemplate()
  170. {
  171. return string.Format("{0}/", Name);
  172. }
  173. public bool Deleted { get; set; }
  174. }
  175. public class EditableStudent
  176. {
  177. public string Id { get; set; }
  178. public string Name { get; set; }
  179. public string Email { get; set; }
  180. }
  181. public class EditableCourse
  182. {
  183. public string Id { get; set; }
  184. public string Name { get; set; }
  185. }
  186. public class Editable
  187. {
  188. public EditableCourse Course { get; set; }
  189. public List<EditableStudent> Students { get; set; }
  190. }
  191. public class Student : BaseIdentity<Student>
  192. {
  193. public new string Id { get; set; }
  194. public string Name { get; set; }
  195. public string Email { get; set; }
  196. public string CourseId { get; set; }
  197. }
  198. public class Course : BaseIdentity<Course>
  199. {
  200. public new string Id { get; set; }
  201. public string Name { get; set; }
  202. public List<string> Students { get; set; }
  203. }
  204. public class Meal : BaseIdentity<Meal>
  205. {
  206. public new string Id { get; set; }
  207. public string Name { get; set; }
  208. }
  209. }
  210. }