I don’t understand why this is happening. I’m using the Go database package to connect to a PostgreSQL database. I loop through fullmsg (88 messages), but after processing about 27 messages, UpdateSyncId stops returning anything and my code hangs
sampleservice.go
func (s *SampleService) SomeFunction(
ctx context.Context,
userId uuid.UUID,
) error {
for _, msg := range fullMsgs {
/*
some operations here
*/
syncId := strconv.FormatUint(msg.SyncId, 10)
if err := s.UserService.UpdateSyncId(ctx, userId, syncId); err != nil {
return fmt.Errorf("failed to update syncid: %v", msg.ID, err)
}
}
return nil
}
userservice.go:
func (s *Userservice) UpdateSyncId(ctx context.Context, userID uuid.UUID, syncId string) error {
return s.UserRepo.UpdateSyncId(ctx, userID, syncId)
}
userrepo.go
func (r *userRepo) UpdateSyncId(ctx context.Context, userID uuid.UUID, maxHistoryId string) error {
// The table structure is assumed to be a 'users' table or a dedicated 'sync_state' table.
// We will assume a 'users' table which has a column for the last processed SyncId.
query := `
UPDATE
users
SET
sync_id = $1
WHERE
id = $2
`
// Execute the update query
result, err := r.DB.ExecContext(ctx, query, maxHistoryId, userID)
if err != nil {
return fmt.Errorf("failed to execute update for user sync id: %w", err)
}
// Optional: Check if exactly one row was updated
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("could not retrieve rows affected after sync id update: %w", err)
}
if rowsAffected == 0 {
return fmt.Errorf("theres no user with that id %s", err)
}
return nil
}
i dont know why it is happening, i've created custom interface for db operation, but i dont think that is the cause.
here's my custom interface implementation for sql/db operations that i use.
type IPsqlDb interface {
QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryRow(query string, args ...interface{}) *sql.Row
Query(query string, args ...interface{}) (*sql.Rows, error)
Exec(query string, args ...interface{}) (sql.Result, error)
}
var (
_ IPsqlDb = (*sql.DB)(nil)
_ IPsqlDb = (*sql.Tx)(nil)
)
pg_stat_activity? Anywait_event?pg_stat_activityI saw a bunch of queries waiting for result, but actual reason for that i usedb.QueryRow()in insert statement instead ofdb.Exec()Since theINSERTwasn’t supposed to return a row,QueryRow()caused the query to wait indefinitely, which led to the blocking. Switching to db.Exec() fixed the problem.UpdateSyncIdfunction, it was caused by anotherInsertfunction inside for loop which I didn’t include in the code above.