当我们说我们已经在数据库和应用程序之间创建了一个连接(可以存储在连接池中)时,“连接”在这里到底意味着什么?
与建立TCP/ TLS
连接有什么关系吗?
它是否为每个连接加载数据库架构?
当数据库架构更改并且正在进行活动事务时,连接(已经加载到应用程序连接池中)的连接会发生什么?
答案 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.php(PHP
)或https://example.com/login.html(HTML
),页面需要访问用户的数据库以检查您插入的凭据是否正确,是否给定的值(例如:用户名:“ 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)
简而言之。 “数据库连接”是您的应用程序过程和数据库的服务过程之间的链接。
客户端:
创建连接时,您的应用程序将存储以下信息:什么数据库地址,用于该连接的套接字,哪个服务器进程负责处理您的请求等。此信息取决于连接驱动程序的实现,并且在数据库之间有所不同
服务器端:
当来自客户端应用程序的请求到达时,数据库将对客户端进行身份验证和授权,并创建一个负责为其服务的新进程或线程。此服务器进程的实现和加载的数据也取决于供应商,并且因数据库而异。
“准备”数据库以服务新客户端的过程需要花费大量时间,而连接池正是在此过程中发挥作用。
连接池:
连接池基本上用于减少打开新连接的需要,并减少了身份验证,授权,创建服务器进程等方面的时间。它允许重用已建立的连接。
当数据库架构更改并且正在进行活动事务时,对连接(已经加载到应用程序连接池中)的连接会发生什么?
首先,数据库不知道任何连接池。对于数据库,这是客户端功能。发生的情况还取决于特定的数据库及其实现。通常,数据库具有阻止机制,可防止在对象仍在使用时对其进行修改,反之亦然。