在应用程序和数据库之间创建连接意味着什么?

问题描述 投票:1回答:3

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

  • 它与建立TCP/ TLS连接有什么关系吗?
  • 它是否为每个连接加载数据库架构?
  • 当数据库架构发生更改并且正在进行活动事务时,连接(已在应用程序连接池中加载)会发生什么?
database oracle postgresql database-connection connection-pooling
3个回答
0
投票

“连接”只不过是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驱动程序中的套接字连接是用SocksSocketImpl完成的,这是一个TCP socket implementation (RFC 1928)

返回我创建的两个连接,如果仔细观察,两个连接的localport是不同的,所以服务器清楚地知道它必须发送回复的位置。

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

它是否为每个连接加载数据库架构?

答:不,这是结果集来处理它。

数据库架构更改时,连接会发生什么

答案:连接和数据库架构是两回事。 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

-1
投票

在这里,您正在谈论的连接意味着应用程序调用以打开和读取/修改/删除数据库或其子项的打开功能。

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

"demoUser" | "password" | "23-03-2019" //示例如上所示

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

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


-1
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.