에서 소개한 내용입니다. DataBase/SQL을 사용할 때 이 11가지 함정에 빠지지 않도록 하세요. 필요한 친구들에게 도움이 되길 바랍니다!
우리는 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동) 언어와 해당 데이터베이스 액세스 라이브러리database/sql
의 열렬한 팬입니다. 아마도 눈으로 볼 수 있듯이 database/sql
은 매우 작지만 이를 통해 많은 일을 할 수 있습니다. 여기에는 상당한 오류 및 기만적인 오류 위험이 포함됩니다. 이 블로그 게시물은 여러분이 같은 실수를 반복하지 않기를 바라면서 과거에 우리가 저지른 몇 가지 실수에 대해 다룹니다.
수명이 긴 함수에는 루프 내에 쿼리가 있으며 루프 내에서 rows.Close()
를 지연하면 메모리와 연결 사용량이 모두 제한 없이 증가합니다. database/sql
的忠实粉丝。正如你可能亲眼看到的那样,database/sql
的体积非常小,但是你可以用它做很多事情。这包括大量的错误和欺骗性错误的风险。这篇博文专门介绍我们过去犯过的一些错误,希望到时候你不会再犯同样的错误。
在循环内延迟。 长生命期函数在循环内有查询,在循环内延迟 rows.Close()
,会导致内存和连接使用量都无限制地增长。
打开许多 db
对象。 请创建一个全局sql.DB
,并且不要为你的 API 服务器应该响应的每个传入 HTTP 请求打开一个新的。否则,你将打开和关闭大量到数据库的 TCP 连接。 TIME_WAIT
状态下的延迟,负载和 TCP 连接很多。
操作完成后不做 rows.Close()
。 忘记关闭 rows 变量意味着连接泄漏。再加上服务器上不断增长的负载,这可能意味着会遇到 max_connections
错误或类似情况。请尽快运行 rows.Close()
,即使它稍后会再次用到(也是无害的)。出于同样的原因,将 db.QueryRow()
和 .Scan()
链接在一起。
预处理语句膨胀。 如果代码以高并发运行,请考虑预处理语句是否是正确的解决方案,因为当连接繁忙时,它们可能会在不同的连接上多次重新预处理。
strconv 或 casts 使代码杂乱无章。 建议将结果扫描到一个你想要的类型的变量中,让 .Scan()
在幕后为你转换。
错误处理和重试导致代码混乱。 让 database/sql
为你处理连接池、重新连接和重试逻辑。
在 rows.Next()
之后忘记检查错误。 别忘了,rows.Next()
循环可能会异常退出。
使用 db.Query()
进行非 SELECT 查询。 如果没有结果集,不要告诉 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동) 你希望在结果集上迭代,否则会泄露连接。
假设后续语句使用相同的连接。 如果连续运行两个语句,则它们很可能在两个不同的连接上运行。运行 LOCK TABLES tbl1 WRITE
,然后运行SELECT * FROM tbl1
,你很可能会阻塞并等待。如果需要保证使用单条语句,则需要使用参数 sql.Tx
。
在使用 TX 的同时访问数据库。 sql.Tx
与事务绑定,但数据库没有绑定,所以访问它不会参与事务。
对一个 NULL
感到惊讶。 你不能将一个 NULL
类型扫描成变量,除非它是 database/sql
包提供的 NullXXX
类型之一(或者是你自己制作的,或者是驱动提供的),否则。仔细检查您的模式,因为如果一个列可以是 NULL
,那么总有一天它会变成 NULL
db
개체를 엽니다. 전역행 변수를 닫는 것을 잊는 것은 연결 누출을 의미합니다. 서버의 로드 증가와 함께 이는sql.DB
를 생성하고 API 서버가 응답해야 하는 모든 수신 HTTP 요청에 대해 새 DB를 열지 마세요. 그렇지 않으면 데이터베이스에 대한 많은 TCP 연결을 열고 닫게 됩니다.TIME_WAIT
상태의 지연 시간, 많은 로드 및 TCP 연결.- 작업이 완료된 후에는
rows.Close()
를 수행하지 마세요.
max_connections
오류 또는 유사한 상황이 발생할 수 있음을 의미할 수 있습니다. 나중에 다시 사용하더라도 최대한 빨리 rows.Close()
를 실행하세요(무해합니다). 같은 이유로 db.QueryRow()
와 .Scan()
을 함께 연결합니다. 🎜🎜.Scan()
이 뒤에서 변환을 수행하도록 하는 것이 좋습니다. 🎜🎜database/sql
이 연결 풀링, 재연결 및 재시도 로직을 처리하도록 하세요. 🎜🎜rows.Next()
이후 오류를 확인하는 것을 잊어버렸습니다. 🎜 잊지 마세요. rows.Next()
루프가 비정상적으로 종료될 수 있습니다. 🎜🎜db.Query()
를 사용하세요. 🎜 결과 세트가 없으면 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)에게 결과 세트를 반복하겠다고 말하지 마세요. 그렇지 않으면 연결이 누출됩니다. 🎜🎜LOCK TABLES tbl1 WRITE
를 실행한 다음 SELECT * FROM tbl1
을 실행하면 차단하고 기다릴 가능성이 높습니다. 단일 문이 사용되는지 확인해야 하는 경우 sql.Tx
매개 변수를 사용해야 합니다. 🎜🎜sql.Tx
는 트랜잭션에 바인딩되어 있지만 데이터베이스는 바인딩되어 있지 않으므로 이에 액세스해도 트랜잭션에 참여하지 않습니다. 🎜🎜NULL
에 놀랐습니다. 🎜 database/sql
패키지(또는 사용자 고유의 패키지)에서 제공하는 NullXXX
유형 중 하나가 아닌 한 NULL
유형을 변수로 스캔할 수 없습니다. 드라이버가 생산 또는 제공), 그렇지 않은 경우. 열이 NULL
일 수 있으면 어느 날 NULL
이 되고 테스트에서 작동하는 것이 프로덕션 축소에서는 작동하지 않을 수 있으므로 스키마를 주의 깊게 확인하십시오. 🎜🎜🎜🎜🎜원본 주소: https://orangematter.solarwinds.com/2017/03/23/common-pitfalls-when-using-database-sql-in-go/🎜🎜번역 주소: https://learnku .com/go/t/50966🎜🎜위 내용은 데이터베이스/SQL을 사용할 때 이러한 11가지 함정에 빠지지 마십시오! (데이터베이스 이동)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!