平原斑马, 埃托沙国家公园, 纳米比亚 (© Mogens Trolle/Shutterstock)

Welcom to 评论 - lizhenqiu blog!

    #438

    作者:广西河池市
    认识函数对象(Function Object)

    可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函数名来进行调用。这些都是代码给用户的印象,而在JavaScript解释执行的时候,实际上每
    个函数都是被维护为一个对象。

    函数对象与其它用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例如日期对象(Date)、数组对象(Array)、字符串对象(String)都是属于内部对象。换句话说,这些内置对象的构造器是由JavaScript本身所定义的:通过执行new Array()这样的语句返回一个对象,JavaScript 内部有一套机制来初始化返回的对象,而不是由用户来指定对象的构造方式。

    在 JavaScript中,函数对象对应的类型是Function,正如数组对象对应的类型是Array,日期对象对应的类型是Date一样,可以通过new Function()来创建一个函数对象,也可以通过function关键字来创建一个对象。为了便于理解,将函数对象的创建和数组对象的创建来比较。先看数组对象:下面两行代码的作用是一样的,都是创建一个数组对象myArray:

    var myArray=[];
    //等价于
    var myArray=new Array();

    同样,下面的两段代码也是等价的,都是创建一个函数myFunction:
    function myFunction(a,b){
    return a+b;
    }
    //等价于
    var myFunction=new Function("a","b","return a+b");

    现在上面的代码还有些难以理解,但是通过和构造数组对象语句的比较,可以清楚的看到函数的对象本质,前面介绍的函数声明是上述代码的第一种方式,而在解释器内部,当遇
    到这种语法时,就会自动构造一个Function 对象,将函数作为一个内部的对象来存储和运行。

    从这里也可以看到,一个函数对象名称(函数变量)和一个普通变量名称具有同样的规范,都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进
    行函数调用。

    也许不会有人通过new Function()的形式来创建一个函数,因为一个函数体通常会有多条语句,如果将它们以一个字符串的形式作为参数传递,那么代码的可读性会非常的差。下面介绍一下其使用语法:
    var funcName=new Function(p1,p2,...,pn,body);
    参数的类型都是字符串,p1 到pn表示所创建函数的参数名称列表,body表示所创建函
    数的函数体语句,而funcName就是所创建函数的名称了。可以不指定任何参数创建一个空
    函数,不指定funcName创建一个无名函数,当然那样的函数什么用处都没有。
    需要注意的是,前面说p1 到pn是参数名称的列表,这意味着p1不仅仅只能代表一个
    参数,它也可以是一个逗号格开的参数列表,例如下面的定义是等价的:
    new Function("a", "b", "c", "return a+b+c")
    new Function("a, b, c", "return a+b+c")
    new Function("a,b", "c", "return a+b+c")
    JavaScript引入Function类型并提供new Function()这样的语法来创建函数并不是毫无意
    义的,在后面可以看到,函数作为一个对象,它本身就可以具有一些方法和属性,而为函数
    对象添加属性和方法就必须借助于Function这个类型。
    现在已经认识到了函数的本质,它其实是一个内部对象,由JavaScript解释器决定其运
    行方式。通过上述代码创建的函数,在程序中可以使用函数名进行调用。于是在本节开头列
    出的函数定义问题也得到了解释:它们都是创建函数对象的正确语法。注意直接在函数声明
    后面加上括号就表示创建完成后立即进行函数调用,例如:
    var i=function (a,b){
    return a+b;
    }(1,2);
    alert(i);
    这段代码会显示变量i 的值等于3。i 是表示返回的值,而不是创建的函数,因为括号
    “(”比等号“=”有更高的优先级。这样的代码可能并不常用,但当用户想在很长的代码段
    中进行模块化设计或者想避免命名冲突,这是一个不错的解决办法。
    需要注意的是,尽管下面两种创建函数的方法是等价的:
    function funcName(){
    //函数体
    }
    //等价于
    var funcName=function(){
    //函数体
    }
    但前面一种方式创建的是有名函数,而后面是创建了一个无名函数,只是让一个变量指
    向了这个无名函数。在使用上仅有一点区别,就是:对于有名函数,它可以出现在调用之后
    再定义;而对于无名函数,它必须是在调用之前就已经定义。例如:
    <script language="JavaScript" type="text/javascript">
    <!--
    func();
    var func=function(){
    alert(1)
    }
    //-->
    </script>
    这段语句将产生func未定义的错误,而:
    <script language="JavaScript" type="text/javascript">
    <!--
    func();
    function func(){
    alert(1)
    }
    //-->
    </script>
    则能够正确执行,甚至下面的语句也能正确执行:
    <script language="JavaScript" type="text/javascript">
    <!--
    func();
    var someFunc=function func(){
    alert(1)
    }
    //-->
    </script>
    由此可见,尽管JavaScript是一门解释型的语言,但它会在进行函数调用时,检查整个
    代码中是否存在相应的函数定义,这个函数名只有是通过function funcName()形式定义的才
    会有效,而不能是匿名函数。
    文章:javascript中new关键字详解  发表时间:2018-09-07, 14:49:44  
    展开↯

    #439

    作者:广西河池市
    PHP中利用redis实现消息队列处理高并发请求
    将请求存入redis 为了模拟多个用户的请求,使用一个for循环替代 //redis数据入队操作 $redis = new Redis(); $redis->connect('127.0.0.1',6379); for($i=0;$i<50;$i++){ try{ $redis->LPUSH('click',rand(1000,5000)); }catch(Exception $e){ echo $e->getMessage(); } } 在后台进行数据处理 守护进程 //redis数据出队操作,从redis中将请求取出 $redis = new Redis(); $redis->pconnect('127.0.0.1',6379); while(true){ try{ $value = $redis->LPOP('click'); if(!$value){ break; } //var_dump($value)."\n"; /* * 利用$value进行逻辑和数据处理 */ }catch(Exception $e){ echo $e->getMessage(); } }
    Run code
    Cut to clipboard
      #,广西河池市,2018-09-05,17:10:51, 可以把相同用户名并发的列为排队
      #,广西河池市,2018-09-05,17:16:19, 如果是要更新,可以不知道总金额,直接更新就可以:
      update T_Money set totalMoney= totalMoney-50
      Run code
      Cut to clipboard
        #,广西河池市,2018-09-05,17:16:39, 另外,可以考虑用更新锁updlock:
        begin tran declare @totalMoney decimal(12,4); select @totalMoney=totalMoney from T_Money with(updlock) update T_Money set totalMoney= @totalMoney-100 commit
        Run code
        Cut to clipboard
          #,广西河池市,2018-09-05,17:17:19, 乐观并发控制,一般能也只是指对于读和写之间,而不是写和写之间的。
          #,广西河池市,2018-09-05,17:17:55, 我理解的加了更新锁的执行顺序是
          1、T1进来 查询到了totalMoney
          2、T2进来 想查询totalMoney 但发现这一行有个更新锁而且T1没有commit,所以等待
          3、T1提交,释放更新锁
          4、T2能查询totalMoney了 继续执行了
          #,广西河池市,2018-09-05,17:20:44, 楼主看一下数据库锁的概念吧,更新操作会加排他锁(之前还有更新锁),所以两个更新操作不会并发的
          简单回答你的问题的话,update确实是原子操作
          #,广西河池市,2018-09-05,17:28:56,@2, 先更新(更新会锁表) 然后在查询 如果金额超出预期 直接回滚 ,更新中 将加减运算放在sql中执行 可以保证数据准确性。
          文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-05, 16:45:34  
          展开↯

          #440

          作者:广西河池市
          时间复杂度
          时间复杂度简单的理解就是执行语句的条数。如果有循环和递归,则忽略简单语句,直接算循环和递归的语句执行次数。

          比如:
          int x = 1;//时间复杂度为O(1) for(int i=0; i<n; i++) { System.out.println(i); }//时间复杂度为O(n)
          Run code
          Cut to clipboard

            具体例子:
            1、O(1)
            int x = 1;
            Run code
            Cut to clipboard

              2、O(n)
              for(int i=0; i<n; i++) { System.out.println(i); }
              Run code
              Cut to clipboard


                int n = 8, count = 0;; for(int i=1; i<=n; i *= 2) { count++; }
                Run code
                Cut to clipboard


                  int n = 8, count = 0;; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { count++; } }
                  Run code
                  Cut to clipboard


                    int n = 8, count = 0;; for(int i=1; i<=n; i *= 2) { for(int j=1; j<=n; j++) { count++; } }
                    Run code
                    Cut to clipboard

                      所举例子都比较简单。

                      空间复杂度
                      空间复杂度也很简单的理解为临时变量占用的存储空间。一个简单例子:
                      //交换两个变量x和y int x=1, y=2; int temp = x; x = y; y = temp;
                      Run code
                      Cut to clipboard

                        一个临时变量temp,所以空间复杂度为O(1)。
                        #,广西河池市,2018-09-05,16:02:50, 其他常见复杂度

                        除了常数阶、线性阶、平方阶、对数阶,还有如下时间复杂度:
                        f(n)=nlogn时,时间复杂度为O(nlogn),可以称为nlogn阶。
                        f(n)=n³时,时间复杂度为O(n³),可以称为立方阶。
                        f(n)=2ⁿ时,时间复杂度为O(2ⁿ),可以称为指数阶。
                        f(n)=n!时,时间复杂度为O(n!),可以称为阶乘阶。
                        f(n)=(√n时,时间复杂度为O(√n),可以称为平方根阶。
                        #,广西河池市,2018-09-05,16:03:13,
                        #,广西河池市,2018-09-05,16:04:31, n[/th] logn[/th] √n[/th] nlogn[/th] n²[/th] 2ⁿ[/th] n![/th] 5[/td] 2[/td] 2[/td] 10[/td] 25[/td] 32[/td] 120[/td] 10[/td] 3[/td] 3[/td] 30[/td] 100[/td] 1024[/td] 3628800[/td] 50[/td] 5[/td] 7[/td] 250[/td] 2500[/td] 约10^15[/td] 约3.0*10^64[/td] 100[/td] 6[/td] 10[/td] 600[/td] 10000[/td] 约10^30[/td] 约9.3*10^157[/td] 1000[/td] 9[/td] 31[/td] 9000[/td] 1000 000[/td] 约10^300[/td] 约4.0*10^2567[/td]
                        #,广西河池市,2018-09-05,16:09:01,
                        n logn √n nlogn 2ⁿ n!
                        5 2 2 10 25 32 120
                        10 3 3 30 100 1024 3628800
                        50 5 7 250 2500 约10^15 约3.0*10^64
                        100 6 10 600 10000 约10^30 约9.3*10^157
                        1000 9 31 9000 1000 000 约10^300 约4.0*10^2567
                        #,广西河池市,2018-09-05,17:04:41,
                        文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-05, 15:23:29  
                        展开↯

                        #441

                        作者:广西河池市
                        时间复杂度和空间复杂度

                        算法复杂度分为时间复杂度和空间复杂度。

                        其作用:
                        时间复杂度是指执行算法所需要的计算工作量;
                        而空间复杂度是指执行这个算法所需要的内存空间。
                        (算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度)。

                        简单来说,时间复杂度指的是语句执行次数,空间复杂度指的是算法所占的存储空间

                        时间复杂度
                        计算时间复杂度的方法:

                        用常数1代替运行时间中的所有加法常数
                        修改后的运行次数函数中,只保留最高阶项
                        去除最高阶项的系数
                        按数量级递增排列,常见的时间复杂度有:
                        常数阶O(1),对数阶O(log2n),线性阶O(n),
                        线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),…,
                        k次方阶O(nk),指数阶O(2n)。
                        随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

                        举个栗子:
                        sum = n*(n+1)/2; //时间复杂度O(1) for(int i = 0; i < n; i++){ printf("%d ",i); } //时间复杂度O(n) for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ printf("%d ",i); } } //时间复杂度O(n^2) for(int i = 0; i < n; i++){ for(int j = i; j < n; j++){ printf("%d ",i); } } //运行次数为(1+n)*n/2 //时间复杂度O(n^2) int i = 1, n = 100; while(i < n){ i = i * 2; } //设执行次数为x. 2^x = n 即x = log2n //时间复杂度O(log2n)
                        Run code
                        Cut to clipboard

                          最坏时间复杂度和平均时间复杂度
                          最坏情况下的时间复杂度称最坏时间复杂度。一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。
                           这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会比任何更长。
                           平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,算法的期望运行时间。设每种情况的出现的概率为pi,平均时间复杂度则为sum(pi*f(n))

                          常用排序算法的时间复杂度
                          最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(nlog2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(nlog2n) 不稳定 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(nlog2n) O(nlog2n) 不稳定 O(1) 希尔排序 O O 不稳定 O(1)
                          Run code
                          Cut to clipboard

                            空间复杂度
                            空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。

                            对于一个算法来说,空间复杂度和时间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当追求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。

                            有时我们可以用空间来换取时间以达到目的。
                            #,广西河池市,2018-09-05,15:15:16, 时间复杂度大概就是运行时间和输入规模的函数,简单的说,一个函数处理 n 个数字,需要 f(n) 秒的时间,时间复杂度就为 O(f(n));空间复杂度把时间换成内存
                            #,广西河池市,2018-09-05,15:15:30,
                            时间复杂度O(n)表示程序运行时间跟n有关,并且是线性关系。
                            空间复杂度O(1),表示所需空间为常量,并且与n无关。
                            #,广西河池市,2018-09-05,15:15:59,
                            要在 hash 表中找到一个元素就是 O(1)
                            要在无序数组中找到一个元素就是 O(n)

                            访问数组的第 n 个元素是 O(1)
                            访问链表的第 n 个元素是 O(n)

                            我给你一个简单的判断方法:
                            如果实现中没有循环就是 O(1)
                            如果实现中有一个循环就是 O(n)
                            #,广西河池市,2018-09-05,15:17:28, 举个简单的例子,要从0加到n,我们会这么写:
                            int sum = 0;
                            for(int i = 0; i<=n; ++i)
                            {
                            sum += i;
                            }
                            一共算了n次加法,那么就说这个时间复杂度是O(n)。当然O(n)的精确的概念是,是n的最高次方,比如,某个计算共计算了3n + 2次,那么这个时间复杂度也是O(n),因为3n + 2中的最高次方是n。

                            如果代码这么写:
                            int sum = 0;
                            for(int i = 0; i<=n; ++i)
                            {
                            for(int j = 0; j <=n; ++j)
                            {
                            sum += (i + j);
                            }
                            }

                            很显然一共算了n^2次加法,那么就说这个时间复杂度是O(n^2),和上面类似,如果某个算法计算了3*n^2 + n + 1次,其时间复杂度仍然是O(n^2),因为3*n^2 + n + 1中最高的次方是n^2

                            所谓O(1)就是计算的次数是个常量,我们还以上面从0加到n的例子来说,如果我们用等差数列的公式,那么,代码可以这么写:
                            int sum = n * (n + 1) / 2
                            不管n有多大(当然不能溢出了),通过上面的公式只需计算一次,也就说计算的次数是不变的,这种情况的时间复杂度就可以说成O(1)。 再比如如果某个计算,不管其他条件怎么变化,均只需计算5次即可得出结果,那么这种情况的时间复杂度,也是O(1)。
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-05, 15:10:24  
                            展开↯

                            #442

                            作者:广西河池市
                            数据库高并发情况下重复值写入的避免 字段组合约束

                            10线程同时操作,频繁出现插入同样数据的问题。虽然在插入数据的时候使用了:
                            insert inti tablename(fields....) select @t1,@t2,@t3 from tablename where not exists (select id from tablename where t1=@t1,t2=@t2,t3=@t3)
                            当时还是在高并发的情况下无效。此语句也包含在存储过程中。(之前也尝试线判断有无记录再看是否写入,无效)。

                            因此,对于此类情况还是需要从数据库的根本来解决,就是约束。否则数据库的原子操作细不到我所需要的层面。
                            添加约束的命令行用得人不多,网上每次找SQL语句都累死,还是写下来好了。
                            需要的关键就叫做 字段组合约束唯一性
                            alter table tablename add CONSTRAINT NewUniqueName Unique(t1,t2,t3)
                            这样可以保证三个字段组合不重复
                            在生产系统数据库的调整真是锱铢必较。。。。。。
                            对于数据库读操作的重复暂时没有好的解决方法,就是读数据库某些条目同时将这些条目某个字段修改为1,然后其他进程读的时候就不会重复读取。但是在多线程情况下即使我使用了SQL SERVER 2005最新的特性,就是类似update...output into到临时表的方法:

                            update tablename set OnCheck=1,LastLockTime=getdate(),LastChecktime=getdate()
                            output deleted.ID into @newtb
                            where ID in
                            (select id from tablename where Oncheck=0)
                            还是会造成重复读。难道没有更好的办法了吗?
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-04, 16:08:42  
                            展开↯

                            #443

                            作者:广西河池市
                            反引号一般在Esc键的下方,和~在一起。它是为了区分MySQL的保留字与普通字符而引入的符号。
                            create table desc 报错
                            create table `desc` 成功
                            一般我们建表时都会将表名,库名都加上反引号来保证语句的执行度。
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-04, 11:07:56  
                            展开↯

                            #444

                            作者:广西河池市
                            时间复杂度O(1)与O(n)
                            时间复杂度是一个函数,它定量描述了该算法的运行时间。常见的时间复杂度有以下几种。
                            1,log(2)n,n,n log(2)n ,n的平方,n的三次方,2的n次方,n!
                            1指的是常数。即,无论算法的输入n是多大,都不会影响到算法的运行时间。这种是最优的算法。而n!(阶乘)是非常差的算法。当n变大时,算法所需的时间是不可接受的。
                            用通俗的话来描述,我们假设n=1所需的时间为1秒。那么当n = 10,000时。
                            O(1)的算法需要1秒执行完毕。
                            O(n)的算法需要10,000秒 ≈ 2.7小时 执行完毕。
                            O(n2)的算法需要100,000,000秒 ≈ 3.17年 执行完毕。
                            O(n!)的算法需要XXXXXXXX(系统的计算器已经算不出来了)。
                            可见算法的时间复杂度影响有多大。
                            所以O(1)和O(n)差了2.7小时,区别显而易见。
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-04, 11:03:16  
                            展开↯

                            #445

                            作者:广西河池市
                            农行卡
                            李振球
                            622848 083830840 9179
                            文章:@意见反馈/技术支持/伊网/安企网  发表时间:2018-09-04, 10:28:35  
                            展开↯

                            #446

                            作者:广西河池市
                            高并发系统的限流

                            1.计数器

                            2.滑动窗口

                            3.漏桶算法

                            4.令牌桶算法
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-03, 15:31:22  
                            展开↯

                            #447

                            作者:广西河池市
                            mysql的锁和存取钱

                            在处理锁的问题上,经常听到:共享锁、排它锁、悲观锁、乐观锁、行级锁、表级锁。

                            共享锁: 就是在读取数据的时候,给数据添加一个共享锁。共享和共享直接是不冲突的,但是和排他锁是冲突的。
                            排他锁: 更新数据的时候,安装排他锁,禁止其他一切行为。


                            场 景:老公去在 ATM 上取钱,老婆在柜台存钱,假设这个账户中有 1000 元。老公首先执行查询操作,查询到账户余额为 1000 此时程序 将 1000 拿到内存中,老公取了200 元,程序就执行了更新操作将账户余额改为 800,但是当老公的程序没有 commit 的时候,老婆查询账户,此时账户余额还是 1000 元,老婆存入 200 元,程序执行了更新操作将账户余额改为 1200,然后老公将更新语句提交,接着老婆也将更新语句提交。最后导致的结果就是该账户的余额为 1200,这就是更新丢失的问题。引发更新丢失的根源就是查询上,因为双方都是根据从数据库查询到的数据再对数据库中的数据进行更新的。


                            解决更新丢失有三个方案:
                            (1) 将事务隔离级别设置为最高,采用死锁策略。
                            (2) 采用悲观锁,悲观锁不是数据库中真正的锁,是人们看待事务的态度。
                            (3) 采用乐观锁,乐观锁也不是数据库中真正的锁。


                            如 果我们采用的是第一个方案时,老公进行查询操作,数据库为表增加了共享锁,老婆进行查询操作时数据库也增加了一个共享锁。但是当老公进行更新数据库操作 时,由于老婆拿着共享锁,导致老公不能增加排它锁,老婆进行更新操作时,因为老公拿着共享锁,导致老婆也拿不到排它锁,这就发生了死锁现象,你等我,我等你。在 mysql 中,处理死锁的方案是释放掉一方的锁。这样就保证了一方更新成功,但是这种性能极低,因为数据库频繁在解决死锁问题。


                            悲观锁(更新多,查询少时用)
                            如果我们采用的是第二个方案时,即采用悲观锁。就是我们在操作数据库时采用悲观的态度,认为别人会在此时并发访问数据库。
                            我们在查询语句中 select * from account where name='aaa' for update; 等于加了排它锁。
                            当老公查询余额的时候,select money from account where name='aaa' for update; 增加了排它锁,
                            老婆查询账户余额的时候, select money from account where name='aaa' for update; 也要求对数据库加排它锁,
                            因为老公已经拿到了排它锁,导致老婆不能加锁,所以老婆只有等待老公执行完毕,释放掉锁以后才能继续操作。


                            乐观锁(更新少,查询多时用)
                            如 果我们采用的是第三个方案时,即采用乐观锁,就是我们在操作数据库的时候会认为没有其它用户并发访问,但是乐观锁也不是完全乐观的,乐观锁是采用版本号的 方式进行控制的。在数据库表中有一列版本号。从数据库中查询的时候,将版本号也查询过来,在进行更新操作的时候,将版本号加1,查询条件的版本号还是查询过来的版本号。
                            比如:
                            老公执行查询操作
                            select money,version from account where name='aaa';
                            假设此时查询到的版本号为 0,
                            老公在进行更新操作
                            update account set money=money+100,version=version+1 where name='aaa' and version=0;
                            未提交时老婆来查询,查询到的版本号依然是 0,
                            老婆也执行更新操作
                            update account set money=money+100,version=version+1 where name='aaa' and version=0;
                            现在老公提交了事务,老婆再提交事务的时候发现版本号为 0 的记录没有了,所以就避免了数据丢失的问题。不过这种情况也导致了多个用户更新操作时,只有一个用户的更新被执行。


                            行级别的锁:
                            select * from employee where employeeID=9857 for update; where 后边是索引列 不是索引列那么就为表级别的锁
                            文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-03, 15:26:34  
                            展开↯

                            #448

                            作者:广西河池市
                            PDO 的事务处理

                            事务处理具有四个特性:原子性、一致性、独立性、持久性。
                            并不是所有的数据库都支持事务处理的,PDO 为能够执行事务处理的数据库提供事务支持。

                            配置事务处理需注意:
                            1、关闭 PDO 的自动提交;
                            $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
                            Run code
                            Cut to clipboard

                              2、开启一个事务需要的方法;
                              $pdo->beginTransaction(); // 开启一个事务 $pdo->commit(); // 提交事务 $pdo->rollback(); // 回滚事务
                              Run code
                              Cut to clipboard

                                3、一般事务处理是运行在 try...catch...语句中,当事务失败时执行 catch 代码段。
                                <?php try { $pdo->beginTransaction(); // 开启一个事务 $row = null; $row = $pdo->exec("xxx"); // 执行第一个 SQL if (!$row) throw new PDOException('提示信息或执行动作'); // 如出现异常提示信息或执行动作 $row = $pdo->exec("xxx"); // 执行第二个 SQL if (!$row) throw new PDOException('提示信息或执行动作'); $pdo->commit(); } catch (PDOException $e) { $pdo->rollback(); // 执行失败,事务回滚 exit($e->getMessage()); } ?>
                                Run code
                                Cut to clipboard

                                  在事务中的 SQL 语句,如果出现错误,那么所有的 SQL 都不执行。当所有 SQL 有无误的时候,才提交执行。
                                  文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-09-03, 14:44:47  
                                  展开↯

                                  #449

                                  作者:广西河池市
                                  结论:
                                  1、不管有木有出现异常,finally块中代码都会执行;
                                  2、当try和catch中有return时,finally仍然会执行;
                                  3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
                                  4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
                                  #,广西河池市,2018-09-01,16:30:43, 任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
                                  如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
                                  编译器把finally中的return实现为一个warning。
                                  #,广西河池市,2018-09-01,16:31:39, 在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
                                  在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
                                  因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
                                  它应该使用栈保存返回值。
                                  #,广西河池市,2018-09-01,16:33:09, 如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,: 1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。 2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
                                  #,广西河池市,2018-09-01,16:33:53, 因为使用栈保存返回值,即使finally中执行i++,但是影响不到之前保存下来的具体的值。 所以return影响不了基本型的值。 而修改list ,map,自定义类等引用类型时,虽然进入finally之前保存了引用的地址,所以在finally中引用地址指向的内容改变了, 影响了返回值。
                                  #,广西河池市,2018-09-01,17:31:48, :try{ return;}catch(){return;} finally{return;} 程序执行try块中return之前(包括return语句中的表达式运算)代码; 有异常:执行catch块中return之前(包括return语句中的表达式运算)代码; 则再执行finally块,因为finally块中有return所以提前退出。 无异常:则再执行finally块,因为finally块中有return所以提前退出。 finally中有return会吃掉异常的
                                  #,广西河池市,2018-09-01,17:32:23, 1.影响返回结果的前提是在 非 finally 语句块中有 return 且非基本类型 2.不影响返回结果 的前提是 非 finally 块中有return 且为基本类型 这也解释了,为什么Date类型是被修改的,究其本质 基本类型在栈中存储,返回的是真实的值,而引用类型返回的是其浅拷贝堆地址.所以才会改变~
                                  #,广西河池市,2018-09-01,17:32:49, 基本数据类型是不能修改的,其他的可以修改,包括date
                                  #,广西河池市,2018-09-01,17:33:44, date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时候指定了一个常量值保存了起来,所以在finally块中修改的其实不是date底层所指向的那个副本,而是对类似于基本数据类型的修改,所以返回的结果仍然是一开始编译好的时候指定的副本。也就是没变的原因。 而其他的对象(引用类型)则是被finally块中的代码改变了所引用变量的真实数据,所以发生了改变。 也就是说,严格来讲,Date类型是个伪对象类型。 以上均为个人观点,如果有误,还望指出,大家一起研究。 :)
                                  文章:finally代码块  发表时间:2018-09-01, 16:30:09  
                                  展开↯

                                  #450

                                  作者:广西河池市
                                  即使try里包含continue,break,return,try块结束后,finally块也会执行。
                                  文章:finally代码块  发表时间:2018-09-01, 16:28:53  
                                  展开↯

                                  #451

                                  作者:广西河池市
                                  我觉得当try,finally都有return时,不能叫做覆盖,因为try中的return只执行了表达式,然后放在某个空间,但是并没有执行return(因为一旦执行return程序就结束了),然后执行finally里面的代码,接着finally中遇到return直接结束了程序,所以应该说是执行了try中return的表达式,而被finally中的return提前结束比较好,并不是finally中的return覆盖了try中的return。
                                  #,广西河池市,2018-09-01,16:26:57, 对于基本类型而言 是值传递 所以2被缓存的是值 而不是变量的地址 再return出去就是2
                                  #,广西河池市,2018-09-01,16:27:14, String类型不可变 也就是String a = "abc";后,存储"abc"字符串的地址的内容不可变,而a变量的重新赋值是通过指向另一块内存地址来实现的。同int型变量。String型变量暂存的是"abc"的存储地址,因此不会发生变化。你可以用StringBuffer、StringBuilder等可变字符类型来对比。
                                  文章:finally代码块  发表时间:2018-09-01, 16:26:11  
                                  展开↯

                                  #452

                                  作者:广西河池市
                                  Mysql查询某字段值重复的数据
                                  查询user表中,user_name字段值重复的数据及重复次数
                                  select user_name,count(*) as count from user group by user_name having count>1;
                                  Run code
                                  Cut to clipboard
                                    文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-08-31, 20:11:30  
                                    展开↯

                                    #453

                                    作者:广西河池市
                                    文章:PHP高并发Redis MySQL重复插入测试笔记  发表时间:2018-08-31, 20:01:36  
                                    展开↯

                                    #454

                                    作者:广西河池市
                                    第一:如果线程1插入订单的过程中,线程2再去插入此时线程2会返回“订单已存在”的提示 ,然后问题是如果线程1插入失败,那么最终结果是数据库里并没有这个订单,但是线程2的用户却看到了“订单已存在” 这样的“错误”提示
                                    第二:关于数据库事务的问题,在ssh这种框架里,经常出现配置的事务是在service方法执行前开启事务,在方法执行完以后提交事务,如果是这种情况的话,那还是会出现数据重复的问题,比如线程1 执行完 MemcacheUtil.del(key); 方法时 此时线程1的事务还没有提交(也就是说数据库里还没有相应的数据),但是缓存里的key已经被删掉了,与此同时线程2看不到数据库里的数据,缓存里的数据也没有
                                    #,广西河池市,2018-08-31,14:53:49, 多台服务器部署,MemcacheUtil 要保证是全局的,不然也有问题
                                    文章:处理高并发情况下的DB插入  发表时间:2018-08-31, 14:53:36  
                                    展开↯

                                    #455

                                    作者:广西河池市宜州市
                                    PHP中利用redis实现消息队列处理高并发请求
                                    将请求存入redis 为了模拟多个用户的请求,使用一个for循环替代 //redis数据入队操作 $redis = new Redis(); $redis->connect('127.0.0.1',6379); for($i=0;$i<50;$i++){ try{ $redis->LPUSH('click',rand(1000,5000)); }catch(Exception $e){ echo $e->getMessage(); } } 在后台进行数据处理 守护进程 //redis数据出队操作,从redis中将请求取出 $redis = new Redis(); $redis->pconnect('127.0.0.1',6379); while(true){ try{ $value = $redis->LPOP('click'); if(!$value){ break; } //var_dump($value)."\n"; /* * 利用$value进行逻辑和数据处理 */ }catch(Exception $e){ echo $e->getMessage(); } }
                                    Run code
                                    Cut to clipboard
                                      #,广西河池市宜州市,2018-08-30,18:09:43,
                                      //关于redis事务的案例 header("content-type:text/html;charset=utf-8"); $redis = new redis(); $redis->connect('localhost', 6379); //$result = $redis->connect('localhost', 6379); //$redis = Yii::app()->redis; $redis->set("testName","33"); //$mywatchkey = $redis->get("mywatchkey"); $mywatchkey = $redis->get('testName'); //($test);exit; $rob_total = 100; //抢购数量 if($mywatchkey<$rob_total){ $redis->watch("testName"); $redis->multi(); //设置延迟,方便测试效果。 sleep(5); //插入抢购数据 $redis->hSet("testName","user_id_".mt_rand(1, 9999),time()); $redis->set("testName",$mywatchkey+1); $rob_result = $redis->exec(); if($rob_result){ $mywatchlist = $redis->hGetAll("testName"); echo "抢购成功!<br/>"; echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>"; echo "用户列表:<pre>"; var_dump($mywatchlist); }else{ echo "手气不好,再抢购!";exit; } }
                                      Run code
                                      Cut to clipboard
                                        #,广西河池市宜州市,2018-08-30,18:17:30,
                                        先将商品库存存入队列:
                                        <?php $store=1000; //商品库存 $redis=new Redis(); $result=$redis->connect('127.0.0.1',6379); $res=$redis->llen('goods_store'); for($i=0; $i<$store; $i++){ $redis->lpush('goods_store',1); } echo $redis->llen('goods_store'); ?>
                                        Run code
                                        Cut to clipboard

                                          客户执行下单操作:
                                          $redis=new Redis(); $result=$redis->connect('127.0.0.1',6379); $count = $redis->lpop('goods_store'); if(!$count){ echo '抢购失败!'; return; }
                                          Run code
                                          Cut to clipboard
                                            文章:php redis 学习笔记  发表时间:2018-08-30, 18:08:32  
                                            展开↯

                                            #456

                                            作者:广西河池市宜州市
                                            文章:程序员编程常用网页工具集[游戏]  发表时间:2018-08-24, 16:26:17  
                                            展开↯
                                            你好,残忍屏蔽广告

                                            确定要清除编辑框内容吗?

                                            该删除操作将不可恢复。

                                            删除 取消

                                            激活Windows

                                            转到"设置"以激活Windows。