【问题标题】:What does creating a connection between an application and database mean?在应用程序和数据库之间创建连接是什么意思?
【发布时间】:2019-08-14 11:45:53
【问题描述】:

当我们说我们在数据库和应用程序之间创建了一个连接(可以存储在连接池中)时,“连接”在这里的真正含义是什么?

  • 与建立TCP/ TLS 连接有什么关系吗?

  • 它是否在每次连接时都加载数据库架构?

  • 当数据库架构发生更改并且正在进行活动事务时,连接(已加载到应用程序连接池中)会发生什么情况?

【问题讨论】:

    标签: database oracle postgresql database-connection connection-pooling


    【解决方案1】:

    这里你所说的连接是指应用程序调用的打开函数来打开和读取/修改/删除数据库或其子数据库。

    例如,如果我们谈论 PHP 文件(用于在服务器中加载网站请求,例如 HTML)或 HTML 文件,您在其中登录的页面名称为:https://example.com/login.phpPHP) 或https://example.com/login.html (HTML) 并且页面需要访问用户的数据库以检查您插入的凭据是否正确,如果给定的值(例如:用户名:“demoUser”和密码: "password*1234"),作为特定表中的行存在于数据库中。数据库内部可以包含无限的表和无限的行。一个只有一个名为 Users 的表的简单数据库示例: username | password | date_created // 表格列

    "demoUser" | "password" | "23-03-2019" // 上面的例子

    "user1213" | "passw0rd" | "04-02-2019" //第二个用户示例 那么在上面如果应用程序需要验证该值是否存在于该数据库中,应用程序的操作系统将通过一个简单的文件读取访问数据库文件通常带有.db,然后它将读取每行查找值。

    为此,login.php/login.html 页面中的代码调用运行文件的服务器,服务器打开数据库,然后服务器进行查询(代码请求检查数据库的内容),并像数据库是一个带有(例如:).db 的简单文件一样执行它。这里的连接代表查询

    【讨论】:

    • 您深入研究了 PHP 并解释了表格,同时将实际主题放在一边。
    【解决方案2】:

    简单来说。 “数据库连接”是您的应用程序进程和数据库的服务进程之间的链接。

    客户端:
    当您创建连接时,您的应用程序会存储以下信息:数据库地址是什么、用于连接的套接字、负责处理您的请求的服务器进程等。这些信息取决于连接驱动程序的实现,并且因数据库而异.

    服务器端:
    当来自客户端应用程序的请求到达时,数据库执行客户端的身份验证和授权,并创建一个新的进程或线程来负责为它提供服务。此服务器进程加载的实现和数据也取决于供应商,并且因数据库而异。
    “准备”数据库以服务新客户端的过程需要大量时间,而这正是连接池提供帮助的地方。

    连接池:
    连接池主要用于减少打开新连接的需要以及在身份验证、授权、创建服务器进程等方面浪费时间。它允许重用已建立的连接。
    当数据库架构更改并且正在进行活动事务时,连接(已加载到应用程序连接池中)会发生什么情况?
    首先,数据库不知道任何连接池。对于数据库,它是一个客户端功能。发生的事情还取决于特定的数据库及其实现。通常数据库有一个阻塞机制来防止对象在它们仍在使用时被修改,反之亦然。

    【讨论】:

    • 我知道什么是连接驱动程序(并且它因供应商而异)并且服务器进行身份验证并且应用程序将其保存在连接池中。问题是关于“连接”到底是什么,让我举个例子,在 TCP 3 路连接握手中,操作系统维护一个队列,直到收到确认。但是,什么是“连接”,它是否存储模式?如果架构更改,连接会发生什么情况?
    • 如果您深入解释“是一个链接”它是如何创建的(TCP/套接字...)如果数据库架构发生变化,该链接会发生什么情况会更有帮助
    • @Vishrant,TCP 和 Socket。而且这种连接与数据库模式无关。如果架构更改 - 链接仍然处于活动状态(不要与事务混淆)。
    • 然后有趣的帖子寻找stackoverflow.com/questions/2783813/… 当存在活动连接并且架构更改时会引发此错误。
    • @Vishrant,这只是我写的阻塞机制的一部分。但是“连接”仍然存在。只是来自数据库(使用连接)的消息表明某些操作无法执行。如果您正在谈论的连接不存在,则用户甚至不会收到此消息。
    【解决方案3】:

    “A Connection”只是a Socket 的详细信息,以及额外的详细信息(如用户名、密码等)。 每个连接都有不同的套接字连接。

    例如:

    连接 1:

    Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]
    

    连接 2:

    Socket[addr=localhost/127.0.0.1,port=1030,localport=51246]
    

    我在单个 JVM 进程中创建了两个连接,以演示服务器如何知道要在哪个 Socket 中发送回复。 A socket,如果我根据 UNIX 定义是用于进程间通信的special file

    srwxr-xr-x. 1 root root 0 Mar  3 19:30 /tmp/somesocket
    

    创建套接字时(即创建此特殊套接字文件时;how to create a socket?this)操作系统会创建一个指向该文件的文件描述符。服务器通过以下属性区分 Socket: Ref.

    {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}
    

    PROTOCOL:我以postgres为例,postgres驱动中的socket连接是用SocksSocketImpl完成的,即TCP socket implementation (RFC 1928)

    返回我创建的两个连接,如果您仔细查看 localport,这两个连接是不同的,因此服务器清楚地知道它必须在哪里发回回复。

    现在您可以在操作系统中打开的文件(或文件描述符)的数量受到限制,因此建议不要让您的连接悬空(称为连接泄漏)

    它是否在每次连接时都加载数据库架构?

    回答:不,是 ResultSet 负责处理它。

    当数据库架构改变时连接会发生什么

    Answer: 连接和数据库架构是两个不同的东西。 Connection 只是定义了如何与另一个进程通信。数据库模式是应用程序和数据库之间的契约,应用程序可能会抛出契约被破坏的错误,或者它可能会忽略它。


    如果你有兴趣深入挖掘,你应该给一个连接对象添加一个断点,下面是它的样子(见FileDescriptor

    connection = {Jdbc4Connection@777} 
    args = {String[0]@776} 
    connection = {Jdbc4Connection@777} 
     _clientInfo = null
     rsHoldability = 2
     savepointId = 0
     logger = {Logger@778} 
     creatingURL = "dbc:postgresql://localhost:1030/postgres"
      value = {char[40]@795} 
      hash = 0
     openStackTrace = null
     protoConnection = {ProtocolConnectionImpl@780} 
      serverVersion = "10.7"
      cancelPid = 19672
      cancelKey = 1633313435
      standardConformingStrings = true
      transactionState = 0
      warnings = null
      closed = false
      notifications = {ArrayList@796}  size = 0
      pgStream = {PGStream@797} 
       host = "localhost"
       port = 1030
       _int4buf = {byte[4]@802} 
       _int2buf = {byte[2]@803} 
       connection = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
        created = true
        bound = true
        connected = true
        closed = false
        closeLock = {Object@811} 
        shutIn = false
        shutOut = false
        impl = {SocksSocketImpl@812} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
         server = null
         serverPort = 1080
         external_address = null
         useV4 = false
         cmdsock = null
         cmdIn = null
         cmdOut = null
         applicationSetProxy = false
         impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
          exclusiveBind = true
          isReuseAddress = false
          timeout = 0
          trafficClass = 0
          shut_rd = false
          shut_wr = false
          socketInputStream = {SocketInputStream@819} 
           eof = false
           impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
           temp = null
           socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
            created = true
            bound = true
            connected = true
            closed = false
            closeLock = {Object@811} 
            shutIn = false
            shutOut = false
            impl = {SocksSocketImpl@812} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
             server = null
             serverPort = 1080
             external_address = null
             useV4 = false
             cmdsock = null
             cmdIn = null
             cmdOut = null
             applicationSetProxy = false
             impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
             timeout = 0
             trafficClass = 0
             shut_rd = false
             shut_wr = false
             socketInputStream = null
             socketOutputStream = null
             fdUseCount = 0
             fdLock = {Object@815} 
             closePending = false
             CONNECTION_NOT_RESET = 0
             CONNECTION_RESET_PENDING = 1
             CONNECTION_RESET = 2
             resetState = 0
             resetLock = {Object@816} 
             stream = false
             socket = null
             serverSocket = null
             fd = {FileDescriptor@817} 
             address = null
             port = 0
             localport = 0
            oldImpl = false
           closing = false
           fd = {FileDescriptor@817} 
            fd = 1260
            handle = -1
            parent = {SocketInputStream@819} 
             eof = false
             impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
             temp = null
             socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
             closing = false
             fd = {FileDescriptor@817} 
              fd = 1260
              handle = -1
              parent = {SocketInputStream@819} 
               eof = false
               impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
                exclusiveBind = true
                isReuseAddress = false
                timeout = 0
                trafficClass = 0
                shut_rd = false
                shut_wr = false
                socketInputStream = {SocketInputStream@819} 
                socketOutputStream = {SocketOutputStream@820} 
                fdUseCount = 0
                fdLock = {Object@821} 
                closePending = false
                CONNECTION_NOT_RESET = 0
                CONNECTION_RESET_PENDING = 1
                CONNECTION_RESET = 2
                resetState = 0
                resetLock = {Object@822} 
                stream = true
                socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
                serverSocket = null
                fd = {FileDescriptor@817} 
                address = {Inet4Address@823} "localhost/127.0.0.1"
                port = 1030
                localport = 51099
               temp = null
               socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
               closing = false
               fd = {FileDescriptor@817} 
               path = null
               channel = null
               closeLock = {Object@826} 
               closed = false
              otherParents = {ArrayList@833}  size = 2
              closed = false
             path = null
             channel = null
             closeLock = {Object@826} 
             closed = false
            otherParents = {ArrayList@833}  size = 2
            closed = false
           path = null
           channel = null
           closeLock = {Object@826} 
           closed = false
          socketOutputStream = {SocketOutputStream@820} 
           impl = {DualStackPlainSocketImpl@814} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
           temp = {byte[1]@843} 
           socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
           closing = false
           fd = {FileDescriptor@817} 
           append = false
           channel = null
           path = null
           closeLock = {Object@844} 
           closed = false
          fdUseCount = 0
          fdLock = {Object@821} 
          closePending = false
          CONNECTION_NOT_RESET = 0
          CONNECTION_RESET_PENDING = 1
          CONNECTION_RESET = 2
          resetState = 0
          resetLock = {Object@822} 
          stream = true
          socket = {Socket@804} "Socket[addr=localhost/127.0.0.1,port=1030,localport=51099]"
          serverSocket = null
          fd = {FileDescriptor@817} 
          address = {Inet4Address@823} "localhost/127.0.0.1"
          port = 1030
          localport = 51099
         timeout = 0
         trafficClass = 0
         shut_rd = false
         shut_wr = false
         socketInputStream = null
         socketOutputStream = null
         fdUseCount = 0
         fdLock = {Object@815} 
         closePending = false
         CONNECTION_NOT_RESET = 0
         CONNECTION_RESET_PENDING = 1
         CONNECTION_RESET = 2
         resetState = 0
         resetLock = {Object@816} 
         stream = false
         socket = null
         serverSocket = null
         fd = {FileDescriptor@817} 
         address = null
         port = 0
         localport = 0
        oldImpl = false
       pg_input = {VisibleBufferedInputStream@805} 
       pg_output = {BufferedOutputStream@806} 
       streamBuffer = null
       encoding = {Encoding@807} "UTF-8"
       encodingWriter = {OutputStreamWriter@808} 
      user = "postgres"
      database = "postgres"
      executor = {QueryExecutorImpl@800} 
      logger = {Logger@778} 
     compatible = "9.0"
     dbVersionNumber = "10.7"
     commitQuery = {SimpleQuery@783} "COMMIT"
     rollbackQuery = {SimpleQuery@784} "ROLLBACK"
     _typeCache = {TypeInfoCache@785} 
     prepareThreshold = 5
     autoCommit = true
     readOnly = false
     bindStringAsVarchar = true
     firstWarning = null
     timestampUtils = {TimestampUtils@786} 
     typemap = null
     fastpath = null
     largeobject = null
     metadata = null
     copyManager = null
    

    【讨论】:

      猜你喜欢
      • 2019-04-19
      • 2011-12-18
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多