@nurzhannogerbek

Как в GO через многопоточность обрабатывать данные из базы данных?

Здравствуйте, товарищи! Помогите пожалуйста разобраться.

В Golang приложении есть однопоточное приложение. Приложение при помощи библиотеки GORM из базы данных (PostgreSQL) получает список всех продуктов. Далее циклом пробегает по каждой и в зависимости от значения столбца status обновляет у продукта значение столбца blocked.

var Tracker = func() {
	var products []models.Products

	// Получаем список продуктов из базы данных
	if err := db.Find(&products).Error; err != nil {
		log.Fatal(err)
		return
	}

	// Парсим список продуктов
	for i := 0; i < len(products); i++ {
		product := models.Product{}

		// В зависимости от статуса продукта выполнить разные действия.
		if products[i].Status == 1 {
			if err := db.Model(&product).Update("blocked", false).Error; err != nil {
				log.Println(err)
				return
			}
		} else if products[i].Status == 2 {
			if err := db.Model(&product).Update("blocked", true).Error; err != nil {
				log.Println(err)
				return
			}
		}
	}
}


Данный однопоточную логику пытаюсь перенести на многопоточность. Насколько мой следующий код правильный на ваш взгляд и какие узкие места здесь есть? Как еще можно оптимизировать скорость отработки?

var Tracker = func() {
	var products []models.Products

	// Получаем список продуктов из базы данных
	if err := db.Find(&products).Error; err != nil {
		log.Fatal(err)
		return
	}

	for _, product := range products {
		go Checker(product)
	}
}

func Checker(product models.Product) {
	if product.Status == 1 {
		if err := db.Model(&product).Update("blocked", false).Error; err != nil {
			log.Println(err)
			return
		}
	} else if product.Status == 2 {
		if err := db.Model(&product).Update("blocked", true).Error; err != nil {
			log.Println(err)
			return
		}
	}
}
  • Вопрос задан
  • 821 просмотр
Решения вопроса 2
tumbler
@tumbler
бекенд-разработчик на python
По-моему это всё делается в один запрос к БД: UPDATE products SET blocked = status == 2 WHERE status in (1,2)
Ответ написан
nikonor
@nikonor
Программист go, perl
если отойти от того, что это реально делается одном запросом (см. пример выше), то тут есть что улучшить.

во-первых, я не знаком с этим ORM, но, как мне кажется, тут явно не хватает транзакции.
во-вторых, если записей будет хрелиард, то рутин будет многовато. я бы сделал n воркеров, а задачу им кидал бы через канал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы