Sobes.tech
Middle+

// Бізде өнімдер туралы ақпарат алудың әдісі бар, бұл әдіс өте жиі шақырылады // Бұл кодта қандай да бір мәселе бар ма және оны қалай түзетуге болады? PostgreSQL дерекқоры func (r *ProductRepository) GetProductDetails(ctx context.Context, productIDs []int) []Product { products := make([]Product, 0, len(productIDs)) for _, id := range productIDs { go func(id int) { var p Product query := "SELECT name, price, description FROM products WHERE id = $1" err := r.db.QueryRowContext(ctx, query, id).Scan(&p.Name, &p.Price, &p.Desc) if err != nil { r.logger.Error("өнімді алу кезінде қате", "err", err) return } products = append(products, p) }(id) } return products }

sobes.tech AI

AI-дан жауап

Көрсетілген кодта бірнеше мәселе бар:

  1. Параллель түрде products кесіндісіне қосу синхрондаусыз — бұл деректердің жарысуына және кесіндінің зақымдалуына әкелуі мүмкін.
  2. Әрбір ID үшін горутиндерді іске қосу, бір уақытта жұмыс істеп жатқан горутиндердің санын бақыламай, бұл дерекқорға шамадан тыс жүктеме түсіруі мүмкін.
  3. Әдіс нәтижені дереу қайтару үшін горутиндердің аяқталуын күтпейді, сондықтан нәтиже әрқашан бос болады.

Қалай түзету керек:

  • Барлық өнімдерді бір шақыруда алу үшін IN операторымен бір SQL сұрауын пайдалану тиімдірек және оңайырақ.
  • Егер параллельді қажет болса, sync.WaitGroup және мьютекс пайдалану арқылы кесіндеге қауіпсіз қосу.

Түзетілген мысал бір сұраумен:

func (r *ProductRepository) GetProductDetails(ctx context.Context, productIDs []int) ([]Product, error) {
    query := `SELECT id, name, price, description FROM products WHERE id = ANY($1)`
    rows, err := r.db.QueryContext(ctx, query, pq.Array(productIDs))
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var products []Product
    for rows.Next() {
        var p Product
        if err := rows.Scan(&p.ID, &p.Name, &p.Price, &p.Desc); err != nil {
            return nil, err
        }
        products = append(products, p)
    }
    return products, nil
}

Мұндай тәсіл дерекқорға жүктемені азайтады және бәсекелестікке қарсы мәселелерді жояды.