Your Question
前端触发,对mysql的数据进行同步(删除过时记录)。在同步后,马上进行查询操作。同一个页面的两次请求。 发现查询的数据不对,比较少,多次刷新后正常。正常后再刷新数据又不齐。 感觉是删除时对mysql加了锁。 请问是否有状态查询mysql的表是否为可读状态? 这种问题如何处理?
The document you expected this should be explained
Expected answer
Comment From: herosql
建议使用gorm.DB.Model() 直接操作数据,我在项目中和你遇到了同样的问题,代码如下:
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type RolePermission struct {
ID string `gorm:"primaryKey;column:id" json:"-"`
RoleID string `gorm:"column:role_id" json:"roleId"`
PermissionID string `gorm:"column:permission_id" json:"permissionId"`
}
func (m *RolePermission) TableName() string {
return "role_permission"
}
func main() {
Db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:123456@tcp(127.0.0.1:3306)/hpvdb_test?charset=utf8mb4&parseTime=True&loc=Local",
}), &gorm.Config{
CreateBatchSize: 1000,
})
if err != nil {
panic(err)
}
rolePermission := RolePermission{}
rolePermissionTable := Db.Table("role_permission")
addList := []RolePermission{
RolePermission{
ID: "1",
RoleID: "1",
PermissionID: "1",
},
RolePermission{
ID: "2",
RoleID: "1",
PermissionID: "2",
},
}
rolePermissionTable.Model(rolePermission).CreateInBatches(addList, len(addList))
rolePermissionTable.Model(rolePermission).Delete(&rolePermission, "id = ?", "1")
list := []RolePermission{}
rolePermissionTable.Model(rolePermission).Where("role_id", "1").Find(&list)
fmt.Println("targetList:1", "nowListLength:", len(list))
}
查看数据库,发现role_permission表里存在一条刚插入的数据,这里查询出来,条数却为0。 尝试另一种写法如下:
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type RolePermission struct {
ID string `gorm:"primaryKey;column:id" json:"-"`
RoleID string `gorm:"column:role_id" json:"roleId"`
PermissionID string `gorm:"column:permission_id" json:"permissionId"`
}
func (m *RolePermission) TableName() string {
return "role_permission"
}
func main() {
Db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:123456@tcp(127.0.0.1:3306)/hpvdb_test?charset=utf8mb4&parseTime=True&loc=Local",
}), &gorm.Config{
CreateBatchSize: 1000,
})
if err != nil {
panic(err)
}
rolePermission := RolePermission{}
// rolePermissionTable := Db.Table("role_permission")
addList := []RolePermission{
RolePermission{
ID: "1",
RoleID: "1",
PermissionID: "1",
},
RolePermission{
ID: "2",
RoleID: "1",
PermissionID: "2",
},
}
/*
rolePermissionTable.Model(rolePermission).CreateInBatches(addList, len(addList))
rolePermissionTable.Model(rolePermission).Delete(&rolePermission, "id = ?", "1")
list := []RolePermission{}
rolePermissionTable.Model(rolePermission).Where("role_id", "1").Find(&list)
fmt.Println("targetList:1", "nowListLength:", len(list))
*/
Db.Model(RolePermission{}).CreateInBatches(addList, len(addList))
Db.Model(RolePermission{}).Delete(&rolePermission, "id = ?", "1")
list := []RolePermission{}
Db.Model(RolePermission{}).Where("role_id", "1").Find(&list)
fmt.Println("targetList:1", "nowListLength:", len(list))
}
结果数据正常。
Comment From: limawanyan
感谢!我碰到了类似的问题,单独开启了一个goroutines执行任务,在任务中会有查询数据库的操作,程序运行一段时间后出现查询不到新插入数据库记录(其他程序插入的数据)的情况,重启项目就正常了。 我也是使用的Db.Table("role_permission")这种方式进行数据查询,没有使用Model。我现在声明一个Model,使用Model试试看还会不会出现查询不到新数据的情况。 你有了解到为什么使用Table会出现数据不一致的情况吗?
Comment From: ritbrz
建议使用gorm.DB.Model() 直接操作数据,我在项目中和你遇到了同样的问题,代码如下:
```go package main
import ( "fmt"
"gorm.io/driver/mysql" "gorm.io/gorm" )
type RolePermission struct { ID string
gorm:"primaryKey;column:id" json:"-"RoleID stringgorm:"column:role_id" json:"roleId"PermissionID stringgorm:"column:permission_id" json:"permissionId"}func (m *RolePermission) TableName() string { return "role_permission" }
func main() {
Db, err := gorm.Open(mysql.New(mysql.Config{ DSN: "root:123456@tcp(127.0.0.1:3306)/hpvdb_test?charset=utf8mb4&parseTime=True&loc=Local", }), &gorm.Config{ CreateBatchSize: 1000, })
if err != nil { panic(err) }
rolePermission := RolePermission{} rolePermissionTable := Db.Table("role_permission") addList := []RolePermission{ RolePermission{ ID: "1", RoleID: "1", PermissionID: "1", }, RolePermission{ ID: "2", RoleID: "1", PermissionID: "2", }, } rolePermissionTable.Model(rolePermission).CreateInBatches(addList, len(addList))
rolePermissionTable.Model(rolePermission).Delete(&rolePermission, "id = ?", "1")
list := []RolePermission{} rolePermissionTable.Model(rolePermission).Where("role_id", "1").Find(&list)
fmt.Println("targetList:1", "nowListLength:", len(list)) } ```
查看数据库,发现role_permission表里存在一条刚插入的数据,这里查询出来,条数却为0。 尝试另一种写法如下:
```go package main
import ( "fmt"
"gorm.io/driver/mysql" "gorm.io/gorm" )
type RolePermission struct { ID string
gorm:"primaryKey;column:id" json:"-"RoleID stringgorm:"column:role_id" json:"roleId"PermissionID stringgorm:"column:permission_id" json:"permissionId"}func (m *RolePermission) TableName() string { return "role_permission" }
func main() {
Db, err := gorm.Open(mysql.New(mysql.Config{ DSN: "root:123456@tcp(127.0.0.1:3306)/hpvdb_test?charset=utf8mb4&parseTime=True&loc=Local", }), &gorm.Config{ CreateBatchSize: 1000, })
if err != nil { panic(err) }
rolePermission := RolePermission{} // rolePermissionTable := Db.Table("role_permission") addList := []RolePermission{ RolePermission{ ID: "1", RoleID: "1", PermissionID: "1", }, RolePermission{ ID: "2", RoleID: "1", PermissionID: "2", }, }
/* rolePermissionTable.Model(rolePermission).CreateInBatches(addList, len(addList))
rolePermissionTable.Model(rolePermission).Delete(&rolePermission, "id = ?", "1") list := []RolePermission{} rolePermissionTable.Model(rolePermission).Where("role_id", "1").Find(&list) fmt.Println("targetList:1", "nowListLength:", len(list))*/ Db.Model(RolePermission{}).CreateInBatches(addList, len(addList))
Db.Model(RolePermission{}).Delete(&rolePermission, "id = ?", "1")
list := []RolePermission{} Db.Model(RolePermission{}).Where("role_id", "1").Find(&list) fmt.Println("targetList:1", "nowListLength:", len(list)) } ```
结果数据正常。
By logging the SQL, you can find the where clause in the DELETE operation would be included in your third query when you reuse the *gorm.DB
INSERT INTO `role_permission` (`id`,`role_id`,`permission_id`) VALUES ("1","1","1"),("2","1","2")
DELETE FROM `role_permission` WHERE id = "1"
SELECT * FROM `role_permission` WHERE id = "1" AND `role_id` = "1"