在应用程序和数据库之间建立连接是什么意思?

时间:2019-03-23 19:07:36

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

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

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

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

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

3 个答案:

答案 0 :(得分:0)

“连接”只是 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),操作系统将创建一个指向该文件的文件描述符。服务器通过以下属性区分套接字: Ref.

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

PROTOCOL:我以postgres为例,postgres驱动程序中的套接字连接是通过SocksSocketImpl完成的,TCP socket implementation (RFC 1928)localport

回到我创建的两个连接,如果仔细观察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 ,因为两个连接都不相同,因此服务器清楚地知道必须将答复发送回何处。

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

  

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

答案:不,它是由ResultSet处理的。

  

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

答案:连接和数据库架构是两件事。连接仅定义了如何与另一个进程进行通信。数据库模式是应用程序与数据库之间的契约,应用程序可能会抛出破坏契约的错误,或者可能会忽略它。


如果您有兴趣进行更多挖掘,则应在连接对象上添加一个断点,以下是其外观(请参见FileDescriptor

{{1}}

答案 1 :(得分:-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" //第二个用户示例 然后在上面如果应用程序需要验证该数据库中是否存在该值,则应用程序的操作系统将通过读取一个简单文件来访问数据库,其中 file通常使用.db ,然后它将读取每行查找值。

要执行此操作,login.php / login.html页面中的代码将调用运行该文件的服务器,然后服务器打开数据库,然后服务器接受查询(代码请求以何种方式检入数据库),并将其执行为好像数据库是带有(例如).db的简单文件。这里的连接就是查询

答案 2 :(得分:-1)

简而言之。 “数据库连接”是您的应用程序过程和数据库的服务过程之间的链接。

客户端:
创建连接时,您的应用程序将存储以下信息:什么数据库地址,用于该连接的套接字,哪个服务器进程负责处理您的请求等。此信息取决于连接驱动程序的实现,并且在数据库之间有所不同

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

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