我想选择数据,同时最后登录数据将在当前日期和时间发生变化。
这是我的代码和错误是2023/08/18 15:07:21连接忙碌我已经尝试更新当前日期在许多位置和仍然相同的错误.我已经试着有更多的延迟关闭和仍然相同的错误。我在数据库中的连接是好的,因为我的一些代码是工程和选择是工作,但更新当前日期不是。
// SELECT MEMBER
func SearcMember(c *fiber.Ctx) error {
var request Models.Request
if err := c.BodyParser(&request); err != nil {
return err
}
rows, err := DBConnection.GetDB().Query(ctx, "SELECT id, login, firstname, mi, lastname, email, passwd, institution, area, internet, level, lastlogin, region, loginToken, staffId, mobileNumber, userStat, isLogin FROM members WHERE login = $1 AND passwd = $2", request.Login, request.Password)
if err != nil {
log.Println(err)
return c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
}
defer rows.Close()
var Members []Models.SelectMembers
for rows.Next() {
var Member Models.SelectMembers
var Institution sql.NullString
var Area sql.NullString
var Internet sql.NullString
var Level sql.NullInt32
var LastLogin sql.NullString
var Region sql.NullInt32
var LoginToken sql.NullString
var StaffID sql.NullString
var UserStatus sql.NullInt32
var ISLogin sql.NullInt32
err := rows.Scan(&Member.MembersID, &Member.LogIn, &Member.FullName.FirstName, &Member.FullName.MiddleName, &Member.FullName.LastName, &Member.Email, &Member.Password, &Institution, &Area, &Internet, &Level, &LastLogin, &Region, &LoginToken, &StaffID, &Member.MobileNumber, &UserStatus, &ISLogin)
if err != nil {
log.Println(err)
continue
}
Member.Institution = Institution.String
Member.Area = Area.String
Member.Internet = Internet.String
Member.Level = int(Level.Int32)
Member.LastLogin = LastLogin.String
Member.LoginToken = LoginToken.String
Member.Region = int(Region.Int32)
Member.StaffID = StaffID.String
Member.UserStatus = int(UserStatus.Int32)
Member.ISLogin = int(ISLogin.Int32)
Member.Name = fmt.Sprintf("%s %s %s", Member.FullName.FirstName, Member.FullName.MiddleName, Member.FullName.LastName)
Members = append(Members, Member)
defer rows.Close()
// Update the LastLogin field with the current date and time
if LastLogin.Valid {
currentTime := time.Now().Format("2006-01-02 15:04:05")
// Update the lastlogin field in the database
_, updateErr := DBConnection.GetDB().Exec(ctx, "UPDATE members SET lastlogin = $1 WHERE id = $2", currentTime, Member.MembersID)
log.Print("Nababasa")
if updateErr != nil {
log.Println(updateErr)
}
}
}
return c.Status(fiber.StatusCreated).JSON(Members)
}
这是我的数据库连接
package DBConnection
import (
"context"
"log"
"github.com/jackc/pgx/v4"
)
var db *pgx.Conn
var ctx = context.Background()
func InitDB() {
conn, err := pgx.Connect(ctx, "postgres://postgres:12345@localhost:5432/crd_audit?sslmode=disable")
if err != nil {
log.Fatalf("Unable to connect to database: %v", err)
}
db = conn
}
func GetDB() *pgx.Conn {
return db
}
我想选择数据,同时最后登录数据将在当前日期和时间发生变化。
1条答案
按热度按时间lqfhib0f1#
根据PGX标准:
由pgx.Connect()返回的 *pgx.Conn表示单个连接,并且不是并发安全的。这完全适用于上面这样的简单命令行示例。
所以这是一个单一的连接,你不能在一个连接上同时运行两个命令。当您执行以下操作时,您正在执行此操作(因此出现
conn busy
错误):1.运行查询以从
members
中选择数据1.对于每个结果:
Exec
UPDATE members
(这需要额外的连接)1.关闭初始
select
查询你可以通过重构你的代码来解决这个问题,这样只需要一个连接。有几种方法可以做到这一点,但最简单的是使用
QueryRow
(正如我所期望的那样,您将有数据库约束来防止重复的login
值,因为重复的值是不好的!)。或者(在需要多个结果的情况下),您可以:1.在
members
上运行select
并获取所有结果(完成后运行rows.Close()
)。1.循环通过
Members
切片,为每个切片运行更新(UPDATE members
)。fibre
的使用)正在编写服务器,并且可能需要处理并发请求(例如,您可能同时收到两个登录请求)。更好的解决方案是使用连接池。这将管理多个数据库连接,使您能够同时运行多个查询(与
*pgx.Conn
不同,并发使用也是安全的)。这看起来像这样: