1

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)
)
4
  • 1
    What is the state of the hanging backend in pg_stat_activity? Any wait_event? Commented Nov 16 at 11:05
  • 1
    @Laurenz Albe man thanks, you save my life, when i checked pg_stat_activity I saw a bunch of queries waiting for result, but actual reason for that i use db.QueryRow() in insert statement instead of db.Exec() Since the INSERT wasn’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. Commented Nov 16 at 11:28
  • @Laurenz Albe i mean it wasnt caused by UpdateSyncId function, it was caused by another Insert function inside for loop which I didn’t include in the code above. Commented Nov 16 at 11:34
  • 1
    You could write an answer to your own question; that might help others. Commented Nov 16 at 17:03

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.