PHP 会话写入是原子的吗?
Are PHP session writes atomic?
由于 PHP 会话处理程序在过去存在某种缺陷,我们几年前开发了一个自制的会话处理程序。
但是 PHP 的当前版本似乎已经开发得很好并且缺陷已经消失,我们决定使用 PHP 的默认会话处理程序(因为它比我们使用 dbms 保存会话的处理程序快得多数据 - 有时需要 read/write 兆字节的数据)。
我们唯一找不到答案的问题是 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
在对源代码进行一些挖掘之后,我找到了 function that writes the data to the disk。
3个函数可以被ps_files_write
用来写入数据:
根据上面的链接,所有这些都是“原子的”,因为如果遇到错误(磁盘空间不足 space、未经授权的访问、锁定的文件),它们不会刷新写入缓冲区等)。
ps_files_write
returns 一个状态值(SUCCESS
或 FAILURE
),稍后在 php_session_save_current_state
到 return ERROR
到 PHP 脚本。
所以是的,通常你可以认为会话写入是“原子的”,即使在某些情况下你无法保证(如果突然断电,系统会在微秒内停止,所以什么都不能得救...)。
由于 PHP 会话处理程序在过去存在某种缺陷,我们几年前开发了一个自制的会话处理程序。 但是 PHP 的当前版本似乎已经开发得很好并且缺陷已经消失,我们决定使用 PHP 的默认会话处理程序(因为它比我们使用 dbms 保存会话的处理程序快得多数据 - 有时需要 read/write 兆字节的数据)。
我们唯一找不到答案的问题是 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
在对源代码进行一些挖掘之后,我找到了 function that writes the data to the disk。
3个函数可以被ps_files_write
用来写入数据:
根据上面的链接,所有这些都是“原子的”,因为如果遇到错误(磁盘空间不足 space、未经授权的访问、锁定的文件),它们不会刷新写入缓冲区等)。
ps_files_write
returns 一个状态值(SUCCESS
或 FAILURE
),稍后在 php_session_save_current_state
到 return ERROR
到 PHP 脚本。
所以是的,通常你可以认为会话写入是“原子的”,即使在某些情况下你无法保证(如果突然断电,系统会在微秒内停止,所以什么都不能得救...)。