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)
    }
}

wx20180815-105911 2x

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

Gorm Transaction update RowsAffected is 0

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.

Gorm Transaction update RowsAffected is 0

从你的截图里面看,是你使用的方法不对 不能使用 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.

Gorm Transaction update RowsAffected is 0

从你的截图里面看,是你使用的方法不对 不能使用 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)