php中没有进程锁,有没有什么解决方案?
ringa_lee
ringa_lee 2017-04-11 10:00:12
0
8
526

php中貌似没有进程锁机制,但是在并发订单处理时需要用到进程锁,不知道有没有什么现成的解决方案?我的考虑是使用flock的方式,生成一个文件锁,对文件锁进行检测,如果已经锁定则休眠1秒后再次检测,直到无锁状态再返回执行,不知道这样子的方案可行吗?

ringa_lee
ringa_lee

ringa_lee

répondre à tous(8)
阿神

PHP文件排它锁flock($fp,LOCK_EX)不是用于控制订单并发的吧.
订单并发为什么不用数据库事务?MySQL默认的引擎InnoDB就支持事务.

$db = new mysqli('127.0.0.1','user','pass','dbname',3306);
$db->query('SET AUTOCOMMIT=0');
$db->query('START TRANSACTION');
$db->query($sql);
$db->query('COMMIT');
$db->query('SET AUTOCOMMIT=1');

如果不想用事务,或者引擎比如MyISAM不支持事务,
可以考虑用CAS(Check And Set)版本号乐观锁,保证高并发下的数据一致性.
上面采用的是事务加悲观锁来控制数据库并发,但是如果系统的并发非常大的话,
悲观锁定会给数据库带来比较大的性能问题(其他事务要等待),
这时可以考虑选择使用版本号乐观锁的方法.
就像防止多人编辑一样,给表弄一个版本号字段.
获取数据时拿到版本号和余额,写入时比对版本号,相同则插入,并把版本号加1.

SELECT balance,version FROM user WHERE id=1 AND balance>10;
UPDATE user SET balance=balance-10,version=last_version+1 WHERE id=1 AND version=last_version;

affected_rows返回0表示操作失败.
注意到UPDATE里的last_version为SELECT获取的本次读写的版本号.
上述版本号的方法借鉴了Memcached的CAS(Check And Set)冲突检测机制,这是一个乐观锁,能保证高并发下的数据安全.
这种方法不需要数据库事务的支持,SELECT操作和UPDATE操作的时间跨度再大也没有问题.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!