Example #1
0
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="option">描述与此事务范围关联的事务要求</param>
        /// <param name="timeout">在该时间间隔之后,事务范围将超时并中止此事务。
        /// 非根级事务环境中,仅当option为RequiresNew时有效。
        /// 特:rootScope是Suppress时,根级事务环境就不是rootScope。
        /// </param>
        public MyTransactionScope(System.Transactions.TransactionScopeOption option, TimeSpan timeout)
        {
            this.scopeOption = option;
            this.timeSpan    = timeout;

            /*********************************************************************
            ** rootScope的Option可能是:Required,RequiresNew,Suppress
            ** currentScope不是rootScope的情况下,Option可能是:RequiresNew,Suppress
            **
            ** 备注:因为Root和Current是ThreadStatic,所以处理时不用lock.
            *********************************************************************/

            if (rootScope == null) //设置根级事务环境
            {
                this.scopeStack = null;

                rootScope    = this;
                currentScope = this;
            }
            else //更新当前事务环境
            {
                //两种情况不更新当前事务环境currentScope:
                //  1)向RequiresNew/Required的环境下,创建Required环境;
                //  2)向Suppress的环境下,创建Suppress环境。
                if (option == System.Transactions.TransactionScopeOption.Required)
                {
                    switch (currentScope.ScopeOption)
                    {
                    case System.Transactions.TransactionScopeOption.Required:
                    case System.Transactions.TransactionScopeOption.RequiresNew:
                        this.hostScopeID = currentScope.ScopeID;
                        return;     //不更新Current

                    case System.Transactions.TransactionScopeOption.Suppress:
                    default:
                        break;
                    }
                }
                else if (option == System.Transactions.TransactionScopeOption.Suppress)
                {
                    if (currentScope.ScopeOption == System.Transactions.TransactionScopeOption.Suppress)
                    {
                        this.hostScopeID = currentScope.ScopeID;
                        return; //不更新Current
                    }
                }
                this.hostScopeID = Guid.Empty;

                if (currentScope != null)
                {
                    //更新前,将之前的事务环境加入“事务链”.
                    if (rootScope.scopeStack == null)
                    {
                        rootScope.scopeStack = new Stack <MyTransactionScope>();
                    }
                    rootScope.scopeStack.Push(currentScope);
                }
                currentScope = this;
            }
        }
Example #2
0
        //嵌套事务中,在不同事务环境里对同一条记录做了更新.会在提交时发生死锁.
        public static void Test2(bool showLock)
        {
            Console.WriteLine("\r\n==================\r\nCalling MyTrans.Test2()");

            //string connStr = Manager.GetConnStringOfOra1();
            string connStr = string.Format("Data Source={0};User ID={1};Password={2};Persist Security Info=True;Pooling=true",
                                           "bhdevcomber", //Helper.GetDatasource4OraTNS("192.168.100.52", "1521", "bhdevcomber"), //
                                           "bhdata",
                                           "bhdata");
            DbAccess db = new DbAccess(connStr);

            //确保记录存在,用于验证Update.
            try
            {
                db.Insert("8", "eight-0");
            }
            catch { }
            try
            {
                db.Insert("9", "nine-0");
            }
            catch { }

            Console.WriteLine("Last - 8:{0}", db.SelectEditTimeByCode("8"));
            Console.WriteLine("Last - 9:{0}", db.SelectEditTimeByCode("9"));
            Console.WriteLine("------------------");

            try
            {
                using (MyTransactionScope scope = new MyTransactionScope())
                {
                    if (showLock)
                    {
                        db.Update("8", "eight-1");
                        Console.WriteLine("Update - 8:{0}", db.SelectEditTimeByCode("8"));
                    }

                    db.Update("9", "nine-1");
                    Console.WriteLine("Update - 9:{0}", db.SelectEditTimeByCode("9"));

                    using (MyTransactionScope scope1 = new MyTransactionScope(TransactionScopeOption.RequiresNew))
                    {
                        db.Update("8", "eight-2");
                        Console.WriteLine("Update in inner scope - 8:{0}", db.SelectEditTimeByCode("8"));

                        if (showLock)
                        {
                            db.Update("9", "nine-2");
                            Console.WriteLine("Update in inner scope - 9:{0}", db.SelectEditTimeByCode("9"));
                        }

                        scope1.Complete();
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Trans Error:" + ex.ToString());
            }

            Console.WriteLine("------------------");
            Console.WriteLine("Last - 8:{0}", db.SelectEditTimeByCode("8"));
            Console.WriteLine("Last - 9:{0}", db.SelectEditTimeByCode("9"));
        }
Example #3
0
        public static void Test1()
        {
            Console.WriteLine("\r\n==================\r\nCalling MyTrans.Test1()");

            //string connStr = Manager.GetConnStringOfOra1();
            string connStr = string.Format("Data Source={0};User ID={1};Password={2};Persist Security Info=True;Pooling=true",
                                           "bhdevcomber", //Helper.GetDatasource4OraTNS("192.168.100.52", "1521", "bhdevcomber"), //
                                           "bhdata",
                                           "bhdata");

            DbAccess db = new DbAccess(connStr);

            Console.WriteLine("Last - 0:{0}", db.SelectCreateTimeByCode("0"));
            Console.WriteLine("Last - 1:{0}", db.SelectCreateTimeByCode("1"));
            Console.WriteLine("Last - 2:{0}", db.SelectCreateTimeByCode("2"));
            Console.WriteLine("Last -22:{0}", db.SelectCreateTimeByCode("22"));
            Console.WriteLine("Last - 3:{0}", db.SelectCreateTimeByCode("3"));
            Console.WriteLine("------------------");

            try
            {
                bool commit;
                using (MyTransactionScope scope = new MyTransactionScope(new TimeSpan(0, 1, 20)))
                {
                    try
                    {
                        db.DeleteByCode("0");
                        db.Insert("0", "zero");
                        Console.WriteLine("Insert - 0:{0}", db.SelectCreateTimeByCode("0"));
                        //db.CreateTable();
                        //db.Insert("0", "zero1");
                        commit = true;
                    }
                    catch (Exception ex1)
                    {
                        Console.WriteLine(ex1.ToString());
                        commit = false;
                    }

                    TransactionScopeOption scopeOption1 = TransactionScopeOption.RequiresNew;
                    TransactionScopeOption scopeOption2 = TransactionScopeOption.Suppress;
                    #region Scope1
                    using (MyTransactionScope scope1 = new MyTransactionScope(scopeOption1))
                    {
                        Console.WriteLine("scope1.{0}\r\n{{", scopeOption1.ToString());
                        bool succeed1 = false;
                        try
                        {
                            Console.WriteLine("Read   - 0:{0}", db.SelectCreateTimeByCode("0"));
                            db.DeleteByCode("1");
                            db.Insert("1", "one");
                            Console.WriteLine("Insert - 1:{0}", db.SelectCreateTimeByCode("1"));

                            db.Insert("0", "zero2");
                            //Console.WriteLine("Insert-0:{0}", db.SelectByCode("0"));

                            succeed1 = true;
                        }
                        catch (Exception ex2)
                        {
                            Console.WriteLine(ex2.ToString());
                        }

                        #region Scope2
                        Console.WriteLine("scope2.{0}\r\n{{", scopeOption2.ToString());
                        using (MyTransactionScope scope2 = new MyTransactionScope(scopeOption2))
                        {
                            bool succeed2 = false;
                            try
                            {
                                Console.WriteLine("Read   - 0:{0}", db.SelectCreateTimeByCode("0"));
                                Console.WriteLine("Read   - 1:{0}", db.SelectCreateTimeByCode("1"));

                                db.DeleteByCode("2");
                                db.Insert("2", "two");
                                Console.WriteLine("Insert - 2:{0}", db.SelectCreateTimeByCode("2"));

                                throw new Exception("test");
                                db.DeleteByCode("22");
                                db.Insert("22", "two-two");
                                Console.WriteLine("Insert - 3:{0}", db.SelectCreateTimeByCode("3"));

                                succeed2 = true;
                            }
                            catch (Exception ex2)
                            {
                                Console.WriteLine(ex2.ToString());
                            }

                            //Suppress不需要提交
                            if (scopeOption2 != TransactionScopeOption.Suppress && succeed2)
                            {
                                scope2.Complete();
                                Console.WriteLine("scope2.Complete()\r\n}");
                            }
                            else
                            {
                                Console.WriteLine("}");
                            }
                        }
                        #endregion

                        //Suppress不需要提交
                        if (scopeOption1 != TransactionScopeOption.Suppress && succeed1)
                        {
                            scope1.Complete();
                            Console.WriteLine("scope1.Complete()\r\n}");
                        }
                        else
                        {
                            Console.WriteLine("}");
                        }
                    }
                    #endregion

                    TransactionScopeOption scopeOption3 = TransactionScopeOption.RequiresNew;
                    using (MyTransactionScope scope3 = new MyTransactionScope(scopeOption3))
                    {
                        Console.WriteLine("scope3.{0}\r\n{{", scopeOption3.ToString());
                        bool succeed3 = false;
                        try
                        {
                            Console.WriteLine("Read   - 0:{0}", db.SelectCreateTimeByCode("0"));
                            Console.WriteLine("Read   - 1:{0}", db.SelectCreateTimeByCode("1"));
                            Console.WriteLine("Read   - 2:{0}", db.SelectCreateTimeByCode("2"));

                            db.DeleteByCode("3");
                            db.Insert("3", "three");
                            Console.WriteLine("Insert - 3:{0}", db.SelectCreateTimeByCode("3"));

                            succeed3 = true;
                        }
                        catch (Exception ex3)
                        {
                            Console.WriteLine(ex3.ToString());
                        }

                        //Suppress不需要提交
                        if (scopeOption3 != TransactionScopeOption.Suppress && succeed3)
                        {
                            scope3.Complete();
                            Console.WriteLine("scope3.Complete()\r\n}");
                        }
                        else
                        {
                            Console.WriteLine("}");
                        }
                    }


                    //if (commit)
                    //{
                    //    try
                    //    {
                    //        db.Insert("1", "first1");
                    //    }
                    //    catch (Exception ex1)
                    //    {
                    //        commit = false;
                    //        Console.WriteLine(ex1.ToString());
                    //    }
                    //}

                    if (commit)
                    {
                        scope.Complete();
                        Console.WriteLine("Complete()");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Trans Error:" + ex.ToString());
            }

            Console.WriteLine("------------------");
            Console.WriteLine("Final - 0:{0}", db.SelectCreateTimeByCode("0"));
            Console.WriteLine("Final - 1:{0}", db.SelectCreateTimeByCode("1"));
            Console.WriteLine("Final - 2:{0}", db.SelectCreateTimeByCode("2"));
            Console.WriteLine("Final -22:{0}", db.SelectCreateTimeByCode("22"));
            Console.WriteLine("Final - 3:{0}", db.SelectCreateTimeByCode("3"));
        }
Example #4
0
        /// <summary>
        /// 销毁资源
        /// </summary>
        public void Dispose()
        {
            /*********************************************************************
            ** 说明:不管当前实例是哪个,只会按照“事务链”进行处理。即始终都是处理currentScope。
            **   rootScope的Option可能是:Required,RequiresNew,Suppress
            **   currentScope不是rootScope的情况下,Option可能是:RequiresNew,Suppress
            **
            ** 主体逻辑:
            **   if (currentScope.ScopeOption == Suppress)
            **   {
            **      没有可提交的内容,直接.
            **   }
            **   else
            **   {
            **      提交当前层级事务后,根据“事务链”更新currentScope。
            **   }
            **   根据“事务链”更新currentScope。
            **   如果当前处理的是根级事务,则将事务环境置空。
            *********************************************************************/

            if (rootScope == null || currentScope == null)
            {
                return;
            }
            if (this.hostScopeID != Guid.Empty)
            {
                return;
            }
            if (this.scopeID != currentScope.scopeID)
            {
                throw new ApplicationException("事务调用顺序不正确");
            }

            lock (lockObj)
            {
                try
                {
                    if (currentScope.ScopeOption != System.Transactions.TransactionScopeOption.Suppress)
                    {
                        currentScope.DisposeCore();
                    }
                }
                finally
                {
                    if (rootScope.ScopeID == currentScope.ScopeID)
                    {
                        if (rootScope.scopeStack != null)
                        {
                            rootScope.scopeStack.Clear();
                            rootScope.scopeStack = null;
                        }
                        rootScope    = null;
                        currentScope = null;
                    }
                    else
                    {
                        if (rootScope.scopeStack != null && rootScope.scopeStack.Count > 0)
                        {
                            currentScope = rootScope.scopeStack.Pop();
                        }
                        else
                        {
                            currentScope = rootScope;
                        }
                    }
                }
            }
        }