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


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

    先上代码:

     /// <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,  这里用一个小技巧来保证串行化(保证同一份数据在某一刻加上排他锁仅供一事物所用其他事物等待)先执行更新锁定数据,再执行查询   ,否则会出现并发冲突产生相同滴数据


    作者:ChenLuLouis
    出处:http://www.cnblogs.com/chenlulouis/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-chenlulouisBlog

  • 相关阅读:
    git 配置免密上传,配置ssh key
    spring @value 为什么没有获取到值
    idea 下maven 导入本地jar,以及导入之后 java不能引用问题
    在git远程仓创建项目之后,提交本地项目的使用方法
    mysql 查询数据库参数命令
    spring Existing transaction found for transaction marked with propagation 'never' 解决
    nginx for ubuntu
    spring中for循环中事务
    面向接口编程详解(一)——思想基础
    实战MEF(5):导出元数据
  • 原文地址:https://www.cnblogs.com/chenlulouis/p/1901247.html
Copyright © 2011-2022 走看看