连接管理
本页面解释了 Prisma Client 如何管理数据库连接,包括何时以及如何使用 $connect() 和 $disconnect() 方法、连接池行为以及针对长时间运行和无服务器环境的最佳实践。
PrismaClient 使用以下两种方法连接和断开数据源:
在大多数情况下,您**不需要显式调用这些方法**。PrismaClient 在您运行第一个查询时自动连接,创建一个连接池,并在 Node.js 进程结束时断开连接。
有关不同部署范式(长时间运行的进程和无服务器函数)的连接管理信息,请参阅连接管理指南。
本页面回答的问题
- 何时应该调用 $connect 和 $disconnect?
- Prisma 如何管理连接池?
- 如何在无服务器环境中处理连接?
$connect()
由于 lazy connect(惰性连接)行为,无需调用 $connect():当向 API 发出第一个请求时,PrismaClient 实例会进行惰性连接($connect() 在底层为您调用)。
显式调用 $connect()
如果您需要第一个请求立即响应,并且不能等待建立惰性连接,您可以显式调用 prisma.$connect() 来建立与数据源的连接
const prisma = new PrismaClient()
// run inside `async` function
await prisma.$connect()
$disconnect()
当您调用 $disconnect() 时,Prisma Client 会:
- 运行
beforeExit钩子 - 结束 Query Engine 子进程并关闭所有连接
在像 GraphQL API 这样持续提供请求的长时间运行应用程序中,在每个请求后调用 $disconnect() 是没有意义的——建立连接需要时间,并且在每个请求中都这样做会降低您的应用程序速度。
为了避免长时间运行的应用程序中连接过多,我们建议您在整个应用程序中使用单个 PrismaClient 实例。
显式调用 $disconnect()
您应该显式调用 $disconnect() 的一种情况是脚本:
- **不经常**运行(例如,一个每晚发送电子邮件的计划任务),这意味着它不会从与数据库的长时间连接中受益,*并且*
- 存在于**长时间运行应用程序**的上下文中,例如后台服务。如果应用程序从不关闭,Prisma Client 将永远不会断开连接。
以下脚本创建一个新的 PrismaClient 实例,执行任务,然后断开连接——这会关闭连接池
import { PrismaClient } from '../prisma/generated/client'
const prisma = new PrismaClient()
const emailService = new EmailService()
async function main() {
const allUsers = await prisma.user.findMany()
const emails = allUsers.map((x) => x.email)
await emailService.send(emails, 'Hello!')
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
如果在长时间运行的应用程序的上下文中多次运行上述脚本,*而不*调用 $disconnect(),则每个新的 PrismaClient 实例都会创建一个新的连接池。
退出钩子
从 Prisma ORM 5.0.0 开始,beforeExit 钩子仅适用于二进制查询引擎。
当 Prisma ORM 被外部触发(例如通过 SIGINT 信号)关闭时,beforeExit 钩子会运行,它允许您在 Prisma Client 断开连接*之前*运行代码——例如,在服务优雅关闭时发出查询
const prisma = new PrismaClient()
prisma.$on('beforeExit', async () => {
console.log('beforeExit hook')
// PrismaClient still available
await prisma.message.create({
data: {
message: 'Shutting down server',
},
})
})