Я не могу понять, как выбрать, а затем обновить таблицу с несколькими горутинами. В документации для db и stmt сказано: «безопасно для одновременного использования несколькими горутинами». Также я использую транзакции, но безуспешно. Я хочу запустить 7 горутин и взять каждую строку.
Данные
+--------+-----------+---------------------+
| idTest | someValue | date |
+--------+-----------+---------------------+
| 1 | 1 | 2019-06-11 11:29:42 |
| 2 | 2 | 2019-06-11 11:29:42 |
| 3 | 3 | NULL |
| 4 | 4 | NULL |
| 5 | 5 | NULL |
| 6 | 6 | NULL |
| 7 | 7 | NULL |
+--------+-----------+---------------------+
текущий код
db, err := sql.Open("mysql", strConn)
if err != nil {
fmt.Printf("Troubles in connaction! %s", err)
}
var idTest int
var someValue string
stmt, err := db.Prepare("select idTest,someValue from test where date is null limit 1")
CheckError(err)
defer stmt.Close()
rows, err := stmt.Query()
CheckError(err)
defer rows.Close()
for rows.Next() {
rows.Scan(&idTest, &someValue)
stmt, err = db.Prepare("update test set date = now() where idTest= ?")
CheckError(err)
_, err = stmt.Exec(idTest)
CheckError(err)
}
Каждая горутина имеет db.conn и иногда пытается выбрать и обновить таблицу.
func main() {
for i := 0; i < 7; i++ {
dbConn := "blabla"
go ChildBot(dbConn)
}
var input string
fmt.Scanln(&input)
}
вы должны прочитать данные, а затем запустить горутину.
for rows.Next() {
rows.Scan(&idTest, &someValue)
go func(idTest int) {
stmt, err = db.Prepare("update test set date = now() where idTest= ?")
CheckError(err)
_, err = stmt.Exec(idTest)
CheckError(err)
}(idTest)
}
это сделано таким образом, потому что вы должны сначала прочитать данные, прежде чем что-либо с ними делать. В противном случае следующее чтение может время от времени переопределять ваше предыдущее значение.
Похоже, пришло время изучить параллелизм и использование блочных каналов.
У меня есть 7 горутин с установленной базой данных для каждой горутины. И каждая горутина вызывает эту функцию для выбора и обновления. В .net у меня нет этой проблемы с транзакциями и sql.Open/Close :( Потому что выберите строки блока и другие транзакции, ожидающие окончания предыдущей транзакции.