示例#1
0
        public void NestedTransactionAndRollback()
        {
            var needleA = Transact.CreateNeedle(5);
            var needleB = Transact.CreateNeedle(1);
            var thread  = new Thread(() =>
            {
                using (var transaction = new Transact())
                {
                    needleB.Value = 2;

                    transaction.Commit();

                    using (var transact = new Transact())
                    {
                        needleA.Value = 9;
                        Assert.AreEqual(9, needleA.Value);
                        Assert.AreEqual(2, needleB.Value);

                        transact.Commit();
                    }

                    Assert.AreEqual(9, needleA.Value);
                    Assert.AreEqual(2, needleB.Value);

                    transaction.Rollback();

                    Assert.AreEqual(5, needleA.Value);
                    Assert.AreEqual(2, needleB.Value);

                    using (new Transact())
                    {
                        needleA.Value = 13;
                        Assert.AreEqual(13, needleA.Value);
                        Assert.AreEqual(2, needleB.Value);

                        transaction.Rollback();

                        Assert.AreEqual(5, needleA.Value);
                        Assert.AreEqual(2, needleB.Value);
                    }

                    needleA.Value = 15;
                    transaction.Commit();
                }
            });

            thread.Start();
            thread.Join();

            Assert.AreEqual(15, needleA.Value);
            Assert.AreEqual(2, needleB.Value);
        }
示例#2
0
 public void ReadonlyTransaction() // TODO: Review
 {
     using (var handle = new ManualResetEvent(false))
     {
         int[] count  = { 0, 0 };
         var   needle = Transact.CreateNeedle(5);
         Assert.AreEqual(needle.Value, 5);
         ThreadPool.QueueUserWorkItem
         (
             _ =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 // This one only reads
                 GC.KeepAlive(needle.Value);
                 transact.Commit();
                 Interlocked.Increment(ref count[1]);
             }
         }
         );
         ThreadPool.QueueUserWorkItem
         (
             _ =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 needle.Value += 5;
                 transact.Commit();
                 Interlocked.Increment(ref count[1]);
             }
         }
         );
         while (Thread.VolatileRead(ref count[0]) != 2)
         {
             Thread.Sleep(0);
         }
         handle.Set();
         while (Thread.VolatileRead(ref count[1]) != 2)
         {
             Thread.Sleep(0);
         }
         // There is no reason for failure
         Assert.IsTrue(needle.Value == 10);
         handle.Close();
     }
 }
示例#3
0
 public void NoRaceCondition() // TODO: Review
 {
     using (var handle = new ManualResetEvent(false))
     {
         int[] count   = { 0, 0 };
         var   needleA = Transact.CreateNeedle(5);
         var   needleB = Transact.CreateNeedle(5);
         Assert.AreEqual(needleA.Value, 5);
         Assert.AreEqual(needleB.Value, 5);
         ThreadPool.QueueUserWorkItem
         (
             _ =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 needleA.Value += 2;
                 transact.Commit();
             }
             Interlocked.Increment(ref count[1]);
         }
         );
         ThreadPool.QueueUserWorkItem
         (
             _ =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 needleB.Value += 5;
                 transact.Commit();
             }
             Interlocked.Increment(ref count[1]);
         }
         );
         global::Theraot.Threading.ThreadingHelper.SpinWaitUntil(ref count[0], 2);
         handle.Set();
         global::Theraot.Threading.ThreadingHelper.SpinWaitUntil(ref count[1], 2);
         // Both
         Assert.AreEqual(7, needleA.Value);
         Assert.AreEqual(10, needleB.Value);
         handle.Close();
     }
 }
示例#4
0
        public void Rollback()
        {
            var needleA = Transact.CreateNeedle(5);
            var needleB = Transact.CreateNeedle(5);

            try
            {
                using (var transact = new Transact())
                {
                    const int Movement = 2;
                    needleA.Value += Movement;
                    ThrowException();
                    // Really, it is evident this code will not run
                    needleB.Value -= Movement;
                    transact.Commit();
                }
            }
            catch (Exception exception)
            {
                // Catch'em all
                GC.KeepAlive(exception);
            }
            // We did not commit
            Assert.AreEqual(5, needleA.Value);
            Assert.AreEqual(5, needleB.Value);

            //---

            using (var transact = new Transact())
            {
                needleA.Value = 9;
                Assert.AreEqual(9, needleA.Value);
                Assert.AreEqual(5, needleB.Value);

                transact.Rollback();

                Assert.AreEqual(5, needleA.Value);
                Assert.AreEqual(5, needleB.Value);
            }
            // We did rollback
            Assert.AreEqual(5, needleA.Value);
            Assert.AreEqual(5, needleB.Value);

            using (var transact = new Transact())
            {
                needleA.Value = 9;
                Assert.AreEqual(9, needleA.Value);
                Assert.AreEqual(5, needleB.Value);

                transact.Rollback();

                Assert.AreEqual(5, needleA.Value);
                Assert.AreEqual(5, needleB.Value);
                needleA.Value = 11;
                Assert.AreEqual(11, needleA.Value);
                Assert.AreEqual(5, needleB.Value);

                transact.Commit();
            }

            // We did rollback and commit again
            Assert.AreEqual(11, needleA.Value);
            Assert.AreEqual(5, needleB.Value);
        }
示例#5
0
        public void AbsentTransaction()
        {
            var needle = Transact.CreateNeedle(5);

            Assert.AreEqual(5, needle.Value);
        }