Transaction update RowsAffected is 0
Just like the following code, when it updates, RowsAffected is 0
What version of Go are you using (go version)?
go version go1.10.3 darwin/amd64
Which database and its version are you using?
mysql 5.7
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"log"
)
var db *gorm.DB
func init() {
var err error
db, err = gorm.Open("mysql", "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True")
if err != nil {
panic(err)
}
db.LogMode(true)
}
type UserTest struct {
gorm.Model
Name string
Password string
}
func main() {
ret := db.AutoMigrate(&UserTest{})
if ret.Error != nil {
log.Fatal(ret.Error)
}
user := &UserTest{
Name: "5",
Password: "2",
}
ret = db.Model(&UserTest{}).Create(user)
if ret.Error != nil {
log.Fatal(ret.Error)
}
var users []UserTest
ret = db.Model(&UserTest{}).Find(&users)
if ret.Error != nil {
log.Fatal(ret.Error)
return
}
for _, v := range users {
log.Println(v.Name, v.Password)
}
tx := db.Begin()
ret = tx.Table("user_tests").Where("name = ?", "5").Updates(map[string]interface{}{
"password": "12345",
})
if ret.Error != nil {
log.Fatal(ret.Error)
tx.Rollback()
return
}
log.Println(ret.RowsAffected)
ret = tx.Table("user_tests").Where("name = ?", "4").Updates(map[string]interface{}{
"password": "44444",
})
if ret.Error != nil {
log.Fatal(ret.Error)
tx.Rollback()
return
}
log.Println(ret.RowsAffected)
tx.Commit()
// 重新查
ret = db.Model(&UserTest{}).Find(&users)
if ret.Error != nil {
log.Fatal(ret.Error)
return
}
for _, v := range users {
log.Println(v.Name, v.Password)
}
}
Comment From: pedromorgan
I can't see what the problem (but am stupid), can u provide more detail if possible..
Is this a bug?
Comment From: aimuz
Yes, I think it's a Bug, and this bug's problem leads to the fact that when you update a record the same as a database, you don't get a return record.
Comment From: aimuz
The most important thing is that this Bug's lead occurs only when the transaction occurs, and when the update command is executed separately, the number of rows that can be updated is obtained. I'm puzzled
Comment From: alicksnake22
@aimuz no data with name = 4
Comment From: gozelus
I got the same problem. I find the affected in db debug log is right
UPDATE `orders` SET `status` = 2, `updated_at` = '2019-07-11 19:08:08' WHERE (order_no = 155765990288785421 and status = 1)
[1 rows affected or returned ]
But zero (not right) in return:
tx.Model(&tradeModel.Order{}).
Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)).
Update("status", int16(status))
log.Println(tx.RowsAffected) // is zero
Comment From: aimuz
I don't know if this project is stopped.
Comment From: kutysam
This is affecting me too. Even for delete within a transaction.
Comment From: caojunxyz
I got the same problem
Comment From: AlessandroSechi
Same problem also for me on
go version go1.13.1 linux/amd64
and
github.com/jinzhu/gorm v1.9.11
Comment From: bluebrown
i have the same. db log says one row affected but db.AffectedRows is zero.
Comment From: BeatsKitano
serious bug
Comment From: seon1-kim
this issue isn't solved? I have same issue. So I tried to send query at mysql cli, is working(value updated and rows affected is correct).
Comment From: aimuz
Yes, it hasn't been solved yet
Comment From: CHURLZ
For others coming to this thread, I could verify this works for sqlite3 and postgres.
if ret.RowsAffected == 0 {
tx.Rollback()
return fmt.Errorf("no record found for id %s and status CREATED", _feedback.Id)
} else if ret.RowsAffected > 1 {
tx.Rollback()
return fmt.Errorf("update affected %d rows, maximum allowed = 1", ret.RowsAffected)
}
Comment From: eruca
me too
Comment From: yiippee
have plan to fix this bug? or there is aother way to know the RowsAffected. Thanks a lot.
Comment From: ovdmar
It happened to me too.
Comment From: Bulesxz
Your question does not match your description
Comment From: Bulesxz
I got the same problem. I find the affected in db debug log is right
UPDATE `orders` SET `status` = 2, `updated_at` = '2019-07-11 19:08:08' WHERE (order_no = 155765990288785421 and status = 1) [1 rows affected or returned ]But zero (not right) in return:
tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(tx.RowsAffected) // is zero
tx.RowsAffected Incorrect usage
ret = tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(ret.RowsAffected)
ret.RowsAffected != tx.RowsAffected
Comment From: Bulesxz
tx.RowsAffected Incorrect usage tx not RowsAffected
Comment From: aimuz
tx.RowsAffected Incorrect usage tx not RowsAffected
So how to use it
It seems that I'm not alone in this problem
Comment From: Bulesxz
tx.RowsAffected Incorrect usage tx not RowsAffected
So how to use it
It seems that I'm not alone in this problem
tx.RowsAffected Incorrect usage
ret = tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(ret.RowsAffected)
ret.RowsAffected != tx.RowsAffected
ret replace tx
Comment From: aimuz
tx.RowsAffected Incorrect usage tx not RowsAffected
So how to use it It seems that I'm not alone in this problem
tx.RowsAffected Incorrect usage
ret = tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(ret.RowsAffected)
ret.RowsAffected != tx.RowsAffected
ret replace tx
I don't think you understand me
Although I haven't used it for a long time, by checking my history
There are two updates in the transaction. The first update can get the rowsaffected, while the second update cannot get the correct rowsaffected
If I were to ask questions at that time, I might have more details.
Comment From: Bulesxz
tx.RowsAffected Incorrect usage tx not RowsAffected
So how to use it It seems that I'm not alone in this problem
tx.RowsAffected Incorrect usage ret = tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(ret.RowsAffected) ret.RowsAffected != tx.RowsAffected ret replace tx
I don't think you understand me
Although I haven't used it for a long time, by checking my history
There are two updates in the transaction. The first update can get the rowsaffected, while the second update cannot get the correct rowsaffected
If I were to ask questions at that time, I might have more details.
从你的截图里面看,是你使用的方法不对 不能使用 tx.RowsAffected 这个是个全局的,应该使用ret.RowsAffected (ret 是每一次操作单独调用结果)
Comment From: davenewza
I am also experiencing this issue.
Comment From: akshay-pj-open
I'm also facing this issue, even though it actually inserts the records. Kindly note that for me this bug arises only during batch inserts.
Comment From: LemonNekoGH
tx.RowsAffected Incorrect usage tx not RowsAffected
So how to use it It seems that I'm not alone in this problem
tx.RowsAffected Incorrect usage ret = tx.Model(&tradeModel.Order{}). Where("order_no = ? and status = ?", orderNo, int16(pb.OrderStatus_OrderStatusWaitConfirm)). Update("status", int16(status)) log.Println(ret.RowsAffected) ret.RowsAffected != tx.RowsAffected ret replace tx
I don't think you understand me Although I haven't used it for a long time, by checking my history There are two updates in the transaction. The first update can get the rowsaffected, while the second update cannot get the correct rowsaffected If I were to ask questions at that time, I might have more details.
从你的截图里面看,是你使用的方法不对 不能使用 tx.RowsAffected 这个是个全局的,应该使用ret.RowsAffected (ret 是每一次操作单独调用结果)
谢谢,解决了 Issue solved, thank you
Comment From: Fantomo
It’s 2024 and this bug hasn’t been solved yet
Comment From: rea1shane
When I run
// gorm gen query
d := query.Day
info, err := d.Where(d.ID.Eq(1)).Update(d.Status, 1)
sometimes info.RowsAffected is 1, sometimes is 0. But even though the value is 0, the database is updated successfully.
Comment From: strconv
// wrong case
tx := xx.Begin()
tx.Update(xx).Error
fmt.Println(tx.RowsAffected) // result is 0
// correct case
tx := xx.Begin()
db := tx.Update(xx)
fmt.Println(db.RowsAffected) // result is n
Comment From: BLN-techin-phi
this might not related that much but please allow me to share
about an hour ago, I'm also faced 0 rowsAffected on update some of my data
TLDR; if data is not existed (or was soft-deleted),
trying to update them also make you get 0 rowsAffected
after go through each comment of this issue
I ensured that my code call RowsAffected
from the result of tx.Update(...) not tx.RowsAffected
(using result, from result = tx.Update(...) - like the above comment)
but error still the same right there
finally, after debug more a little bit, I found that update function return the correct result but what cause error is the data in the database
here is pseudo code that might help to understand what happen
// these all below are inside transaction
_ = deleteSomethingByIds(ctx, ids)
_ = updateSomething(ctx, pk, mapDataToUpdate)
I did send empty list of id (the ids) to function to delete items by ids
so Gorm soft-delete every records which make my next query,
that try to update -> found nothing (due to it respect soft-delete boolean flag)