1

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

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

现在,如果我们考虑一个 Web 服务器,特别是 Apache 2.4 运行一个 PHP 7.2 应用程序(在虚拟主机中)和一个由 MariaDB 10.3.10 支持的数据库(如果这很重要的话,在 Fedora 28 上),我假设以下场景(请更正如果我错了,我):

  • 对于每个 Web 应用程序,现在我们使用 Laravel,只要第一个查询命中它所服务的 URL,就会建立一个数据库连接。
  • 随后,它将只有一个数据库会话。提供查询时,连接将保持活动状态,以供应用程序接收的其他查询重用。这意味着如果应用程序最有可能连续接收 24 x 7 的 Web 请求,连接也将保持活动状态,并且只有在我们重新启动 mysqld 或 httpd 时才会断开连接,这甚至可能在几个月内都不会发生。
  • 由于应用程序的所有用户,比如 20 个用户,使用相同的 Apache 服务器和 Laravel 应用程序文件(我假设我可以称之为应用程序实例)所有 20 个用户将通过相同的数据库连接提供服务和数据库会话。

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

问题:

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

1 回答 1

1

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

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

启用连接池后,为请求提供服务的线程将请求从池到进程管理器的连接(无论是它fpm还是mod_php),它会从池中返回一个可用的连接,但仍然至少有与并发请求一样多的会话(除非你达到任何max_限制)。一般参考资料更详细,但作为一个亮点:

持久连接不能让你在同一个链接上打开“用户会话”,它们不能让你有效地建立一个事务,它们不能做很多其他的事情。事实上,要非常清楚地了解这个主题,持久连接不会为您提供任何与它们的非持久兄弟无法实现的功能。

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

您可以参考扩展的连接参考持久连接参考mysqli获取更多信息。

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

于 2018-10-11T08:39:03.503 回答