Implementation of ISessionScope to provide transaction semantics
Inheritance: SessionScope
        public void ExplicitFlushInsideSecondTransactionProblem()
        {
            var comp1 = new Company("comp1");
            var comp2 = new Company("comp2");
            using(new SessionScope())
            {
                comp1.Create();
                comp2.Create();
            }

            using(new SessionScope(FlushAction.Never))
            {
                using(var tx = new TransactionScope(ondispose: OnDispose.Rollback))
                {
                    var comp2a = Company.Find(comp2.Id);
                    comp2a.Name = "changed";
                    tx.VoteCommit();
                }

                using(var scope = new TransactionScope(ondispose: OnDispose.Rollback))
                {
                    var changedCompanies = AR.FindAllByProperty<Company>("Name", "changed");
                    Assert.AreEqual(1, changedCompanies.Count());
                    var e2a = changedCompanies.First();
                    e2a.Delete();

                    scope.Flush();

                    Assert.AreEqual(0, AR.FindAllByProperty<Company>("Name", "changed").Count());
                }
            }
        }
        public void LotsOfNestedTransactionWithDifferentConfigurations()
        {
            using(var root = new TransactionScope())
            {
                using(var t1 = new TransactionScope()) // Isolated
                {
                    var blog = new Blog();

                    Blog.FindAll(); // Just to force a session association

                    using(new TransactionScope(TransactionMode.Inherits))
                    {
                        Blog.FindAll(); // Just to force a session association

                        blog.Author = "hammett";
                        blog.Name = "some name";
                        blog.Save();
                    }

                    using(new TransactionScope(TransactionMode.Inherits))
                    {
                        var post = new Post(blog, "title", "post contents", "Castle");

                        post.Save();
                    }

                    t1.VoteRollBack();
                }

                Blog.FindAll(); // Cant be locked

                using(new TransactionScope())
                {
                    var blog = new Blog();
                    Blog.FindAll(); // Just to force a session association

                    using(new TransactionScope())
                    {
                        Blog.FindAll(); // Just to force a session association

                        blog.Author = "hammett";
                        blog.Name = "some name";
                        blog.Save();
                    }

                    using(var t1n = new TransactionScope(TransactionMode.Inherits))
                    {
                        var post = new Post(blog, "title", "post contents", "Castle");

                        try
                        {
                            post.SaveWithException();
                        }
                        catch(Exception)
                        {
                            t1n.VoteRollBack();
                        }
                    }
                }

                root.VoteCommit();
            }

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.AreEqual(1, blogs.Length);

                var posts = Post.FindAll().ToArray();
                Assert.AreEqual(0, posts.Length);
            }
        }
        public void TransactionScopeUsage()
        {
            using(var scope = new TransactionScope())
            {
                var session1 = scope.OpenSession<Blog>();
                var session2 = scope.OpenSession<Post>();
                var session3 = scope.OpenSession<Blog>();
                var session4 = scope.OpenSession<Post>();

                Assert.IsNotNull(session1);
                Assert.IsNotNull(session2);
                Assert.IsNotNull(session3);
                Assert.IsNotNull(session3);

                Assert.IsTrue(session2 == session1);
                Assert.IsTrue(session3 == session1);
                Assert.IsTrue(session4 == session1);
            }
        }
        public void RollbackVote()
        {
            using(var transaction = new TransactionScope())
            {
                var blog = new Blog {Author = "hammett", Name = "some name"};
                blog.Save();

                var post = new Post(blog, "title", "post contents", "Castle");
                post.Save();

                // pretend something went wrong

                transaction.VoteRollBack();
            }

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.AreEqual(0, blogs.Length);

                var posts = Post.FindAll().ToArray();
                Assert.AreEqual(0, posts.Length);
            }
        }
        public void RollbackUponException()
        {
            using(var transaction = new TransactionScope())
            {
                var blog = new Blog {Author = "hammett", Name = "some name"};
                blog.Save();

                var post = new Post(blog, "title", "post contents", "Castle");

                try
                {
                    post.SaveWithException();
                }
                catch(Exception)
                {
                    transaction.VoteRollBack();
                }
            }

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.AreEqual(0, blogs.Length);

                var posts = Post.FindAll().ToArray();
                Assert.AreEqual(0, posts.Length);
            }
        }
        public void NestedTransactionWithRollbackOnDispose()
        {
            using(new TransactionScope())
            {
                var blog = new Blog();

                using(var t1 = new TransactionScope(TransactionMode.Inherits, ondispose: OnDispose.Rollback))
                {
                    blog.Author = "hammett";
                    blog.Name = "some name";
                    blog.Save();

                    t1.VoteCommit();
                }

                using(var t2 = new TransactionScope(TransactionMode.Inherits, ondispose: OnDispose.Rollback))
                {
                    var post = new Post(blog, "title", "post contents", "Castle");

                    try
                    {
                        post.SaveWithException();

                        t2.VoteCommit(); // Will never be called
                    }
                    catch(Exception)
                    {
                        // t2.VoteRollBack();
                    }
                }
            }

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.AreEqual(0, blogs.Length);

                var posts = Post.FindAll().ToArray();
                Assert.AreEqual(0, posts.Length);
            }
        }
        public void MixingSessionScopeAndTransactionScopes3()
        {
            var b = new Blog();

            using(new SessionScope())
            {
                b.Name = "a";
                b.Author = "x";
                b.Save();

                using(new TransactionScope())
                {
                    for(var i = 1; i <= 10; i++)
                    {
                        var post = new Post(b, "t", "c", "General");
                        post.Save();
                    }
                }
            }

            using(new SessionScope())
            {
                // We should load this outside the transaction scope

                b = Blog.Find(b.Id);

                using(var transaction = new TransactionScope())
                {
                    if (b.Posts.Count > 0)
                        foreach(var p in b.Posts)
                        {
                            p.Delete();
                        }

                    b.Delete();

                    transaction.VoteRollBack();
                }
            }

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.AreEqual(1, blogs.Length);

                var posts = Post.FindAll().ToArray();
                Assert.AreEqual(10, posts.Length);
            }
        }
        public void UsingTransactionScopeWithRollback()
        {
            SqlConnection conn = CreateSqlConnection2();
            ISession session1, session2;
            ITransaction trans1, trans2;

            using(TransactionScope scope = new TransactionScope())
            {
                Blog blog = new Blog {Name = "hammett's blog", Author = "hamilton verissimo"};
                blog.Save();

                session1 = blog.GetCurrentSession();
                trans1 = blog.GetCurrentSession().Transaction;
                Assert.IsNotNull(session1);
                Assert.IsNotNull(session1.Transaction);
                Assert.IsFalse(session1.Transaction.WasCommitted);
                Assert.IsFalse(session1.Transaction.WasRolledBack);

                blog.Evict();
                conn.Open();

                using(new DifferentDatabaseScope(conn))
                {
                    blog.Create();

                    session2 = blog.GetCurrentSession();
                    trans2 = blog.GetCurrentSession().Transaction;
                    Assert.IsNotNull(session2);

                    Assert.IsFalse( Object.ReferenceEquals(session1, session2) );

                    Assert.IsNotNull(session2.Transaction);
                    Assert.IsFalse(session2.Transaction.WasCommitted);
                    Assert.IsFalse(session2.Transaction.WasRolledBack);

                    scope.VoteRollBack();
                }
            }

            Assert.IsFalse(session1.IsOpen);
            Assert.IsFalse(session2.IsOpen);
            Assert.IsFalse(trans1.WasCommitted);
            Assert.IsTrue(trans1.WasRolledBack);
            Assert.IsFalse(trans2.WasCommitted);
            Assert.IsTrue(trans2.WasRolledBack);

            using (new SessionScope()) {
                var blogs = Blog.FindAll().ToArray();
                Assert.IsNotNull( blogs );
                Assert.AreEqual(0, Blog.Count());

                var blogs2 = OtherDbBlog.FindAll().ToArray();
                Assert.IsNotNull( blogs2 );
                Assert.AreEqual(0, OtherDbBlog.Count());
            }
        }