rairlie / laravel-locking-session
为 Laravel 提供会话锁定
v2.0.1
2023-08-17 09:57 UTC
Requires
- php: >=7.4
- illuminate/session: >=5.0
Requires (Dev)
- phpunit/phpunit: ^8.0
This package is auto-updated.
Last update: 2024-09-17 12:20:55 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'
如果目录不存在,则会创建它。
要求
- 对锁目录的写入权限
- POSIX 文件系统锁定,例如 *NIX、Windows(未测试)。