0

0

php中原子操作与文件锁flock的介绍(代码示例)

不言

不言

发布时间:2019-01-28 10:00:48

|

2903人浏览过

|

来源于博客园

转载

本篇文章给大家带来的内容是关于php中原子操作与文件锁flock的介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

php原子操作,文件锁flock,数据库事务

php没有继承posix标准支持的unix锁,只封装了一个linux系统调用flock(信号量也能做成锁),按理也是可以使用锁机制的,虽然效率低一点。
php脚本是运行在fastcgi容器中,而fastcgi是多进程的,所以如果php程序访问了临界资源,势必造成程序结果的不正确性。
估计还要考虑下fastcgi容器的问题

问题描述:黑客用的工具刷我们的后台
取消订单时会有退款,黑客并发取消订单,导致多次退款
如果请求一个一个来,哪怕间隔100毫秒,也是没有问题的

一个PHP处理过程是: 读退款标志,发现没退款, 退款,然后设置已退款标志
问题是多个请求同时到了,读出来的退款标志都是未退款,所以多个请求都退款了
同一个php文件,被同时请求多次,是同一时刻

立即学习PHP免费学习笔记(深入)”;

用php文件锁flock 我们试了不行,还是用C++队列
用C++监听了一个端口,直接接收HTTP包,然后返回HTTP格式的包,PHP程序中用curl访问我这个C程序.
相当于远程调用了,可以部署到其他服务器做分布式了

很多时候,我们并没有考虑我们php代码的并行能力,尤其是在我们的php代码对某个资源可读可写的时候。但这并不是说php的所有操作就都是原子的,事务的,可并行的。由于php脚本是运行在fastcgi容器中,而fastcgi是多进程的,所以如果php程序访问了临界资源,势必造成程序结果的不正确性。

解决问题的办法是使用锁机制。php没有继承posix标准支持的unix锁:比如记录锁fcntl,线程锁等,而只封装了一个linux系统调用flock(信号量也能做成锁),flock形式为flock($fp,$type),其中$fp为文件句柄,而$type为:
/* 当一个文件的打开方式是可读可写的,通常需要向文件加入锁机制 */

1. LOCK_SH 共享锁:
通常为进程向文件请求读操作时需加共享锁。共享锁可支持任意个进程间的读操作,如果写一个加了共享锁的文件则进程阻塞进入SLEEP状态值到共享锁解锁

2. LOCK_EX 独占锁:
通常为进程向文件的写操作加独占锁,一旦文件加上了该锁,则其他任意进程访问该文件时都会阻塞,直到解锁为止。

3. LOCK_UN 解锁:
为加锁的文件句柄解锁

这样的加锁方式必然可以保证加锁程序块的原子性,但同时也牺牲了程序的效率,因此,我们实际的程序中应该在程序的加锁和解锁代码间嵌入尽量少的程序逻辑(尤其是独占锁),保证程序尽快解锁。

最后,附上加上锁机制以后的程序:

蓝心千询
蓝心千询

蓝心千询是vivo推出的一个多功能AI智能助手

下载

普通情况运行该程序,产生正确的结果。

用什么方法可以在业务批量操作时保证原子性呢?
例如:删除多条文章,但在中间有一条已经被删除了,假设这里会出现错误,那如何让整个操作回滚,并定位错误信息呢?
数据库的事务保证原子性但不能定位错误信息,但遇到无法使用事务的场景,应该怎么做呢?

利用数据库的事务来做是最合理的,错误信息可以记录啊,有操作失败抛出错误。
应用逻辑来保证,就是每操作一次做下记录,成功失败都做下记录。中间出错,可以把成功的回滚。一般我们删除是假删除,所以很容易。如果真删除,记录时要记录完整信息。

PHP用文件锁模拟进程锁,实现原子操作
用PHP实现原子操作,而PHP本身并没有提供进程锁机制,用PHP文件锁机制,通过文件锁模拟进程锁实现原子操作。

原子操作的代码之前,使用排他锁打开某个文件,代码如下:

$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
 echo "Failed to open the lock file!"; 
 exit(1);//异常处理
 }
flock ( $fp, LOCK_EX );

原子操作的代码之后,对该文件解锁,并关闭文件,代码如下:

flock ( $fp, LOCK_UN );
fclose ( $fp );

整体伪代码为:

define("LOCK_FILE_PATH", "/tmp/lock");
if( !file_exists(LOCK_FILE_PATH) ){ 
$fp = fopen( LOCK_FILE_PATH, "w" );
fclose ( $fp );
}
$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
echo "Failed to open the lock file!";
exit(1);//异常处理
}
flock ( $fp, LOCK_EX );
//此处添加原子操作代码
flock ( $fp, LOCK_UN );
fclose ( $fp );

以上便可实现PHP原子操作,避免冲突。

php原子操作与mysql原子操作

原子操作常用的方法就是通过数据回滚来实现,用 PHP 来实现数据库回滚操作相当简单:
1, 建立数据库连接
2, mysql_query('BEGIN'); 开启事务
3, $SQL = "..."; 
mysql_query($SQL); 做相应的数据库操作
4, 判断回滚条件:
if(mysql_errno) 

print mysql_error(); 
mysql_query('ROLLBACK'); 出错就回滚 
exit(); 

5,可以重复上述步骤 3 及步骤 4 的操作, 开始的过程(中间可以加入其他操作,不局限于数据库更新,但是注意,最好不要让一个事务时间过长,因为它锁定所有你用到的表,会影响其他程序使用) 
你也可以在几条正确的sql更新语句后故意写一句错误的,看看是否回滚了。
6, 结束回滚操作
mysql_query('COMMIT'); 能够到这里,代表上述数据库操作都没有错,正式提交执行

这就是用 PHP 实现原子操作的整个过程,需要特别注意的是建立支持数据回滚操作的表结构,
另外,除 commit 外也有其它办法可以结束回滚操作。


相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

115

2025.12.24

拼豆图纸在线生成器
拼豆图纸在线生成器

拼豆图纸生成器有PixelBeads在线版、BeadGen和“豆图快转”;推荐通过pixelbeads.online或搜索“beadgen free online”直达官网,避开需注册的诱导页面。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

82

2025.12.24

俄罗斯搜索引擎yandex官方入口地址(最新版)
俄罗斯搜索引擎yandex官方入口地址(最新版)

Yandex官方入口网址是https://yandex.com。用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

546

2025.12.24

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

150

2025.12.24

php框架基础知识汇总
php框架基础知识汇总

php框架是构建web应用程序的架构,提供工具和功能,以简化开发过程。选择合适的框架取决于项目需求和技能水平。实战案例展示了使用laravel构建博客的步骤,包括安装、创建模型、定义路由、编写控制器和呈现视图。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

20

2025.12.24

Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

47

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

7

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

12

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

371

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 7.8万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号