如何保证session的一致性(session.save_handler=sqlite时的一个bug)

tabris17 2009-12-02 09:22:45
php的在页面载入时或调用session_start()时从数据源中读取session数据到$_SESSION变量。
当页面执行完毕或调用session_write_close()时把$_SESSION变量写入数据源。

php默认的session.save_handler=files,可以通过文件锁来实现读写同步,保证session数据的一致性,不会产生问题。然而当使用sqlite作为session handler时,由于没有同步机制,会产生bug。如下代码:

test1.php

session_start();
$_SESSION['data1'] = 'data1';
sleep(10);
session_write_close();



test2.php

session_start();
$_SESSION['data2'] = 'data2';
session_write_close();


在同一浏览器进程里(保证使用相同的session_id),先访问test1.php,再访问test2.php,会发现data2根本没有写入sqlite数据库中。session.save_handler=memcache还没有测试,估计也有这个问题。如果采用默认的files handler会发现test2.php的请求会被挂起直至test1.php执行完毕,这就是文件锁同步机制造成的。

我想到了两种解决方案:
1、实现互斥锁,保证同一session_id访问session数据是同步的,这样会产生一个阻塞的问题(php默认的session实现也会有这个问题)。
2、写入session数据时进行数据合并,不过这样仍然不能完全保证数据一致性。

有没有人曾经碰到过这个问题?有什么解决方案吗?
...全文
595 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
tabris17 2009-12-14
  • 打赏
  • 举报
回复
用文件锁方案解决了,不过高并发下文件锁同步可能会有问题,linux下考虑采用信号量
ruanchao 2009-12-05
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 tabris17 的回复:]
本人阴沟里洗不行啊
[/Quote]

找人翻译一下,提交上去吧
tabris17 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 ruanchao 的回复:]
可以给PHP开发团队反映一下,应该会给你一些建议的
[/Quote]

本人阴沟里洗不行啊
影子Sirk 2009-12-04
  • 打赏
  • 举报
回复
有点意思,这问题,呵呵
fxs_2008 2009-12-04
  • 打赏
  • 举报
回复
请教一下,session.save_handle的配置参数有哪些?找不到文档啊!
fxs_2008 2009-12-04
  • 打赏
  • 举报
回复
关注一下
骄傲青蛙 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 ruanchao 的回复:]
可以给PHP开发团队反映一下,应该会给你一些建议的
[/Quote]

这个好, 直接上官网請求处理bug
ruanchao 2009-12-04
  • 打赏
  • 举报
回复
可以给PHP开发团队反映一下,应该会给你一些建议的
tabris17 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 fxs_2008 的回复:]
请教一下,session.save_handle的配置参数有哪些?找不到文档啊!
[/Quote]

运行php -i
查看 Registered save handlers 一项的信息
一般根据安装的扩展,有files(默认) user memcache sqlite
ms_X0828 2009-12-03
  • 打赏
  • 举报
回复
up
babysc1 2009-12-03
  • 打赏
  • 举报
回复
还真不知道这BUG 呵呵
程序猿之殇 2009-12-03
  • 打赏
  • 举报
回复
关注一下!
foolbirdflyfirst 2009-12-03
  • 打赏
  • 举报
回复
这个问题有意思,帮顶。
待有空测试一下。
tabris17 2009-12-03
  • 打赏
  • 举报
回复
up
tabris17 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 alandy 的回复:]
引用 11 楼 tabris17 的回复:
引用 7 楼 alandy 的回复:
我曾经解决过类似的问题,用线程委托就可以解决此类问题。


你说的现成委托是PHP的解决方案吗?
能具体说说吗?

不是PHP,是做.NET项目时遇到,自己写个线程委托类就解决了啊!PHP你查下看,应该也可以的!
[/Quote]

我想呢,一搜“线程委托”怎么都是说.net的,呵呵
alandy 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 tabris17 的回复:]
引用 7 楼 alandy 的回复:
我曾经解决过类似的问题,用线程委托就可以解决此类问题。


你说的现成委托是PHP的解决方案吗?
能具体说说吗?
[/Quote]
不是PHP,是做.NET项目时遇到,自己写个线程委托类就解决了啊!PHP你查下看,应该也可以的!
tabris17 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yctin 的回复:]
重载session读写方法, 在关键位置自行处理
用rename() 进行缓存替换

[/Quote]

即使采用session_set_save_handler()重载也会有类似的问题,因为PHP没有内置的互斥锁的实现。linux可以使用sem_*系列函数来使用信号量,但是windows下没有类似函数,只能用文件读写锁代替,但是传说在高并发情况下文件锁会失效。
lonelyriver 2009-12-03
  • 打赏
  • 举报
回复
学习
tabris17 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 alandy 的回复:]
我曾经解决过类似的问题,用线程委托就可以解决此类问题。
[/Quote]

你说的现成委托是PHP的解决方案吗?
能具体说说吗?
t240034137 2009-12-03
  • 打赏
  • 举报
回复
关注!
加载更多回复(4)

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧