chenlulouis

暴走笑话 杭州空调维修 杭州燃气灶维修 杭州洗衣机维修 上海ktv酒吧招聘 上海招聘 上海夜场招聘 上海夜场招聘

导航

利用事物(隔离级别)+锁方式串行化保证在高并发环境下数据的一致性代码


根据表结构,说明多个事物操作的是同一份数据。

先上代码:

 /// <summary>
        /// 从数据库获取 UniqueID
        /// </summary>
        /// <returns></returns>
        private int[] GetUniqueIDForSimple(string KeyName, int Count)
        {
            int[] result = new int[]{0, 0};
            OracleConnection conn = new OracleConnection("UID=*;PWD=*;Data Source=*");
            OracleTransaction tran = null;
            DateTime Start;
            DateTime End;
            try
            {
                conn.Open();
                tran = conn.BeginTransaction(IsolationLevel.ReadCommitted);
                ///记录开开始时间
                Start = DateTime.Now;
                ShowMessage("ThreadName:" + Thread.CurrentThread.Name + ", StartDateTime:" + Start);
                OracleCommand updateCmd = new OracleCommand("Update UniqueIDs Set KeyValue = KeyValue + " + Count + " Where KeyName='" + KeyName + "'", conn, tran);
                int rowsAffected = updateCmd.ExecuteNonQuery();
                ///记录结束时间
                End = DateTime.Now;
                TimeSpan span = End - Start;
                ///由于事务提交或者回滚是在 6 秒钟以后,因此这里应该基本都是等待 6秒
                ShowMessage("ThreadName:" + Thread.CurrentThread.Name + ", 等待更新时间:" + span.TotalMilliseconds + "ms");
                ///更新以后等待3秒
                Thread.Sleep(3000);
                OracleCommand selectCmd = new OracleCommand("Select KeyValue From UniqueIDs Where KeyName = '" + KeyName + "'", conn, tran);
                object keyValueObj = selectCmd.ExecuteScalar();
                ///查询以后等待3秒
                Thread.Sleep(3000);
                tran.Commit();
                if (keyValueObj != null)
                {
                    result[1] = Convert.ToInt32(keyValueObj) - 1;
                    result[0] = result[1] - Count + 1;
                }
                return result;
            }
            catch (Exception ex)
            {
                if (tran != null)
                    tran.Rollback();
                return result;
            }
            finally
            {
                conn.Close();
            }
        }
  由于外部系统统一调用这个方法开启事务来获取uniqueid,  这里用一个小技巧来保证串行化(保证同一份数据在某一刻加上排他锁仅供一事物所用其他事物等待)先执行更新锁定数据,再执行查询   ,否则会出现并发冲突产生相同滴数据

posted on 2010-12-09 14:35  chenlulouis  阅读(2292)  评论(4编辑  收藏  举报