由于PHP会话处理程序在过去存在某种缺陷,我们在几年前开发了一个自制的会话处理程序。但是,当前版本的PHP似乎已经开发得很好,缺陷也没有了,我们决定使用PHP的默认会话处理程序(因为它比我们的处理程序快得多,后者使用dbms来保存会话数据,有时需要读取/写入兆字节的数据(。
我们唯一找不到答案的问题是,PHP的默认会话处理程序是否是原子的?
我们知道会话文件是锁定的,所以很容易出现竞争条件,但原子性呢?如果兆字节的数据将被保存在会话文件中,并且在中间发生了一些错误(例如停电、崩溃或磁盘故障(,该怎么办。现在发生了什么?会话数据现在损坏了吗?还是旧数据仍然存在?
我们团队中没有C程序员,但我查看了PHP的源代码,找到了负责将会话写入文件的行,但我找不到s_write((的源代码文件。
ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime));
这是源文件(第487行(:https://github.com/php/php-src/blob/master/ext/session/session.c
在对源代码进行了一些挖掘之后,我找到了将数据写入磁盘的函数。
ps_files_write
可以使用3个功能来写入数据:
_write
,在Win32上prwite
,它似乎是一个UNIX函数,老实说,我对它了解不多write
,基本的C系统调用
根据上面的链接,它们都是";原子";如果遇到错误(磁盘空间不足、未经授权的访问、锁定的文件等(,它们不会刷新写缓冲区
ps_files_write
返回状态值(SUCCESS
或FAILURE
(,然后在php_session_save_current_state
中检查该状态值以向PHP脚本返回ERROR
。
因此,是的,通常您可以将会话写入视为";原子";,即使在某些情况下你无法保证(如果突然断电,系统会在微秒内停止,所以什么都救不了…(。