如何可靠地生成连续数字


How do you reliably generate consecutive numbers?

我正在做一个项目(一个使用Symfony 2用PHP编写的web应用程序),其中有一个要求,各种安全相关的事件被记录。还要求日志文件中的事件连续编号(我想这样就不容易删除项目了)。

我将使用独白(包括Symfony)进行日志记录,我知道我可以用处理器将数字添加到记录中。

我不知道的是如何可靠地生成连续的数字。"可靠"的意思是:没有空白,没有重复的数字。

我能想到的唯一解决方案是让数据库(MySQL通过Doctrine)通过使用一个带有自动增量ID的虚拟表来生成数字,然而,这似乎对日志记录来说有点开销。

还有其他策略吗?

您可以用单个文件模拟自动递增id,该文件包含最后一个id。锁防止竞争条件:

$fp = fopen('/path/to/id.file', 'r+');
flock($fp, LOCK_EX);
$lastId = fgets($fp);
$currentId = $lastId + 1;
fseek($fp, 0);
fputs($currentId);
// place logging here...
flock($fp, LOCK_UN);

如果您想要写入一个文件,我想唯一可靠的方法是在写入新记录之前从该文件读取最大数量-并且在执行此操作时使用文件锁定以避免TOCTTOU问题。基本上就是数据库事务为你做的事情,但是用文件:-)

也许你不需要每次都锁定和读取整个日志文件——也可以只将最后一个数字记录到一个单独的"计数器"文件中,并在读取最后一个数字、写入日志文件和更新计数器文件中的数字期间锁定该数字。