这段时间一直在用PHP做报表,碰到了一些非常头痛的问题,就是有些报表的SQL跑的时间比较长,而当这个报表正没有结束运行的时候,其它的报表页面就绝对被卡住
经过一步步分析,终于找到了病症之处:session
session最常用的就是记录用户的登陆信息,而在不少资料中,会告诉你,session_start()后,无需自己去调用session_commit(),脚本在结束后自动调用session_commit()
如果你的脚本运行的时间很短,自然不会出什么问题,但如果是需要比较长的运行时间的话,就杯具了。
看看下面这两个简单的脚本吧,拿去运行一次,你就知道什么结果了
test.php<html>
    <head>
        <title></title>
    </head>
    <body>
        <?php
        session_start();
        $_SESSION["message"]="我留下的脚印";
        // session_commit(); 
        sleep(20);
        ?>
        休息了20秒钟...
    </body>
</html>test2.php<html>
    <head>
        <title></title>
    </head>
    <body>
        <?php
        session_start();
        //session_commit(); //别担心,session_commit()以后,$_SESSION数组的内容还在.
        echo $_SESSION["message"]."<br/>";
        ?>
        我等到花儿也谢了
    </body>
</html>
先运行test.php,然后20秒之内运行test2.php。按道理,test2.php会一下子就闪出来,但因为test.php还在抓住session不放,于是test2.php就被session_start()卡住了,直到test.php结束后,test2.php才得以继续。
而如果把代码中注释掉的那两行加上的话,才会得到我们所期望的效果。
我被这个小问题困扰了好一阵子,在这里分享一下经验给各位新手们:记住及时的session_commit(),别听那些只会copy的人在那说不用手动调用session_commit(),否则吃苦的就是你

解决方案 »

  1.   

    我认为不是  session的问题,而是 sleep的问题...
      

  2.   

    这是 session_commit() 的说明,也就是session_write_close()void session_write_close ( void )
    End the current session and store session data. Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done. 我用红色显示的地方,意思就是任何时候只有一个脚本文件可以操作session文件
    所以如果不及时session_commit(),而且脚本运行时间过长的话,肯定会影响其它页面对session的读取
      

  3.   

    嗯 翻了一下手册,这个session 的确是 “单线程"的为了防止并发的写入,必须只有一个脚本在操作.所以其实session换成其他只允许单个执行的函数在sleep下也会出现这样的情况。
    该纠结的是 什么东西要运行这么久?大型计算?那是不是不应该采用session更合适些。更搞的是当我把你的第一个页面修改成        <?php        sleep(20);
            session_start();
            $_SESSION["message"]="我留下的脚印";
            ?>
            休息了20秒钟...的时候 问题就解决了... 呵呵
      

  4.   

    报表SQL,有时统计大数据量的报表的时候,需要运行很长的时间
     <?php  sleep(20);
      session_start();
      $_SESSION["message"]="我留下的脚印";
      ?>
    你的这改法,很容易理解,前20秒时间内,因为还没有执行session_start(),所以session文件没有被打开
    所以test2.php可以很快就打开
      

  5.   


    问题是 $_SESSION["message"]="我留下的脚印"; 这个也传递过去了 就在前20秒
      

  6.   


    是.忘记了。那么除了  session_commit 看样子就只有不使用session 或者在 运行代码之后再 session了.
    这个 session_commit 难道不会影响session?
      

  7.   

    session_commit()也就是session_write_close()会把$_SESSION数组的内容写入到服务器上的文件中,但不会清空$_SESSION的变量内容
    session_start()则是打开那个文件,并随时准备写内容
      

  8.   

    thx.这么看来SESSION 在写数据结束的时候 还是顺带的给 write_close比较合适Description:
    ————
    Calling session_start() appears to wait until other scripts have exited
    that are using the same session. My guess is the 1st request locks the 
    session file for exclusive use, and the second request blocks until it 
    can open it.Thank you for taking the time to write to us, but this is not a bug.This is expected, the session file is locked to avoid corruption.