数据库锁和网络服务器如何就数据库会话进行协作?

How database locks and web server collaborate with respect to database sessions?

这个问题的范围很广,例如Web 服务器、数据库服务器、php 应用程序等,因此我怀疑它属于指的是 Whosebug,但是由于这个问题将帮助我们了解如何编写应用程序代码,所以我决定在这里提问。

我对数据库会话和 Web 服务器如何协同工作感到困惑。如果我是对的,当为客户端建立连接时,只会为该连接创建一个会话,并且该会话将持续到连接断开或由于长时间不活动而重新连接。

现在,如果我们考虑一个 Web 服务器,特别是 Apache 2.4 运行 一个 PHP 7.2 应用程序(在虚拟主机中),其数据库由 MariaDB 10.3.10 支持(如果是,则在 Fedora 28 上)根本不重要),我假设以下情况(如果我错了请纠正我):

如果上面提到的所有用例都是正确的,那么数据库锁定的概念似乎很混乱。因为假设我们会发出排他锁,例如lock tables t1 write;,会阻塞其他会话的读写,避免并发会话的脏读写操作。 但是,由于所有 20 个用户同时使用相同的会话和连接,我们无法通过数据库锁定机制获得所需的并发安全性。

问题:

  1. 数据库锁定、显式独占锁定在 Web 应用程序方面如何工作?
  2. 在 Laravel 应用程序收到的每个 Web 请求是否会创建一个新的连接和会话,或者只有一个连接和会话被重用?
  3. 每个数据库连接是否一次只有一个会话?
  4. 这个命令会显示当前活动的会话或连接吗show status wherevariable_name= 'Threads_connected'?如果它显示当前活动连接,我们如何获得当前活动数据库会话?

在这种情况下(大部分)Apache 与会话无关。数据库连接和会话由 php 本身处理。

除非您启用了连接池,否则数据库会话将不会被重用,每个请求都会打开自己的连接并在结束时关闭它。

启用连接池后,为请求提供服务的线程将请求从池到进程管理器的连接(fpmmod_php),并且它将 return来自池的可用 连接,但仍然至少有与并发请求一样多的会话(除非您达到任何max_ 限制)。 general reference 进入更多细节,但作为亮点:

Persistent connections do not give you an ability to open 'user sessions' on the same link, they do not give you an ability to build up a transaction efficiently, and they don't do a whole lot of other things. In fact, to be extremely clear about the subject, persistent connections don't give you any functionality that wasn't possible with their non-persistent brothers.

即使有可用的连接池,管理器也必须 运行 在 return 连接到客户端之前进行一些清理操作。其中一项操作是 table 解锁。

您可以参考 mysqli 扩展的 connections reference and persistent connections reference 了解更多信息。

但是,您所描述的多个客户端会话共享一个连接的操作模式是可能的(并且是实验性的)并且有更多缺点。它被称为 session multiplexing