rairlie/laravel-locking-session

为 Laravel 提供会话锁定

v2.0.1 2023-08-17 09:57 UTC

README

此包通过在底层会话驱动程序周围包装独占锁,在 Laravel 中实现会话锁定。因此,它应该与任何会话后端兼容 - 诸如 cookies、文件、数据库等。(目前仅测试了文件和 cookies)。

它解决了由于并发请求同时更新会话而导致会话数据丢失的问题。这种情况可能发生在执行同时的 XHR 请求时。

示例场景

考虑这种情况:变量 COUNTER 存储在会话中,并且有两个请求同时尝试增加它的值。在没有会话锁定的前提下

Request A: Read session data: COUNTER = 1
Request B: Read session data: COUNTER = 1
Request A: COUNTER = COUNTER + 1
Request B: COUNTER = COUNTER + 1
Request A: Write session data: COUNTER = 2
Request B: Write session data: COUNTER = 2

最终结果:COUNTER = 2

在有会话锁定的前提下,这会变成

Request A: Lock session
Request A: Read session data: COUNTER = 1
Request B: Attempt to lock session - already locked, must wait
Request A: COUNTER = COUNTER + 1
Request A: Write session data: COUNTER = 2
Request A: Release lock
Request B: Acquires lock
Request B: Read session data: COUNTER = 2
Request B: COUNTER = COUNTER + 1
Request B: Write session data: COUNTER = 3
Request B: Release lock

最终结果:COUNTER = 3

会话锁定确保了正确性,但代价是有效地序列化访问会话的并发请求。如果你有一些不使用会话的并发请求,在这些请求上禁用会话中间件,它们仍然可以并发执行。

安装

composer require rairlie/laravel-locking-session

在你的 Laravel 应用中,编辑 config/app.php 并将默认的会话处理器替换为锁定处理器

config/app.php:
- Illuminate\Session\SessionServiceProvider::class,
+ Rairlie\LockingSession\LockingSessionServiceProvider::class,

默认情况下,锁文件被写入系统临时目录下的子目录 'sessionlocks'。你可以使用以下方式指定一个替代路径:

config/session.php:
'lockfile_dir' => '/path/to/my/lockdir'

如果目录不存在,则会创建它。

要求

  1. 对锁目录的写入权限
  2. POSIX 文件系统锁定,例如 *NIX、Windows(未测试)。

兼容性