Heim >Backend-Entwicklung >PHP-Tutorial >php高并发下的疑问。
在高并发下,如果我插入一条数据,返回一个insert_id
,那么这个insert_id
会不会为别人所用呢。如果不被别人所用,php是怎么做到访问隔离的。
在高并发下,如果我插入一条数据,返回一个insert_id
,那么这个insert_id
会不会为别人所用呢。如果不被别人所用,php是怎么做到访问隔离的。
楼主的理解有问题。。。
MySQL的LAST_INSERT_ID()或者说PHP的mysql_insert_id(connection)。
请注意,Connection!
每次插入数据,MySQL会返回数据给【当前的数据库连接】,告知是插入到第几个位置(ID)的。根本不存在什么"
访问隔离
","为别人所用
"之类的问题。
——————————————————————————————————————————————————
数据库的存在,本身就是为了解决并发的问题。
查询是可以并发的(同时读取文件不会有问题)。
插入、修改、删除必须是队列方式(同时修改同一个文件???)。楼主的理解有问题,一个等一个就会一卡一卡的?
举个栗子,现在的一般的机械硬盘的写入速度30-50M/s。
一次SQL写入请求,平均写入3-5KB数据(你TM在逗我,怎么可能这么多),那么理论上,也可以支持10000/s的并发量。
什么叫一卡一卡的 = =
—————————————————————————————————————————————————
回想当年……2333333……
当初我还不会PHP的时候被同学拉去做网站,报名参加活动的那种只有几个网页的网站。
数据提交之后,在PHP里,我就自己定义了一个格式,一条数据一行,把数据全都保存到一个txt文件里。
(在相当长一段时间里,我都觉得,数据库貌似也没那么重要啊,直接读写文件不就完了)
直到后来……
同时对一个文件进行写操作就会发生异常(很底层的问题,操作系统级别的)。
同时对一个文件加锁(防止同时写操作),也可能发生异常(还是操作系统级别的问题)。
对txt的指定位置进行修改,删除,必须从文件里全部读入内存,然后处理,然后写到文件里。
想修改格式,查询,排序……全都要全部读取全部写入。
这时候遇到并发的问题……彻底爆炸,数据各种丢失错误混乱。。。数据库已经基本是相当完美的解决了这些乱七八糟的问题了。。。
嗯,是的,每个请求的链接都是独立的,10个并发就是10个链接对象,所以insert_id永远不会被其他请求的链接所用!!!
php层面的“隔离”
这个就是PHP的“特性”---每个请求都是一个进程,php-fpm每次都会分配一个对应的worker来处理这个请求。
每个操作都在对应的php-fpm下属的worker下进行,内存管理也是一样。
处理完这个进程就关闭。
你插入的返回id是在各自请求对应的php-fpm下属的worker内存中,不会出现你说的情况。
mysql层面的“隔离”
跟引擎有关咯。简单说引擎对应的写入处理不同。MyIASM是表锁,Innodb是行锁,都可以在一定程度上避免并发问题。再高的并发,就要用其他的处理方式了,比如队列等等。
php即便是高并发,单进程连数据库还是单个连接的。
insert id是根据mysql连接的上一条insert语句返回的。
所以对于一个php进程,一个mysql连接,返回的insert id是不会混乱的
兄弟啊,你需要看一本书叫数据库原理
,数据库里面有一个概念叫ACID,事务就两种状态,成功和失败。你这边都insert进去了,那就是成功了,就last insert id
也是这个事务的返回值。
MySQL本身也支持并发,开N个connection去同步的insert,也不会有问题,最多就是慢一点。
PS:PHP能写出来多高的并发??
php中一个请求一般新生成一个mysql连接,多个session同时请求mysql插入操作如何同步,这是mysql解决的问题。mysql 插入操作是加锁的,保证了原子性。
@MrGeneral 说的有部分问题,在这里贴出来,大家补充下:
---每个请求都是一个进程,每次都会启动一个php-fpm。
这句话,每个请求都是一个进程,没错,但是每次都会启动一个php-fpm?
这个是不对的,每次都会启动一个fastcgi的进程,但是这个进程是不是每一次都重新创建的,那倒未必,可能是从php-fpm维护的”进程池“里面取的,也就是说,php-fpm负责进程的管理,部分优化,比如cache住啊,避免了每次都创建进程的开销。而php-fpm本身是常驻的。
求反驳~