当使用OnConflict条款时,我将UpdateAll标志设置为true.我的表有Version字段,也有optmisticLock.Version.

我预计gorm会将包括版本列在内的所有列更新为新版本,以防发生冲突,但版本不会自动更新.

示例:

type TestEntity struct {
  ID string `gorm:varchar(100);primary_key`
  Name string
  Version optimisticlock.Version
}

表中有一行包含条目:

ID: "xyz", Name: "first", Version: 1

我想更新当前行:

testUpdateEntity := &TestEntity{
  ID: "xyz",
  Name: "second",
}

当我 run 时:

dres := u.db.WithContext(context.TODO()).Clauses(clause.OnConflict{
        UpdateAll: true,
    }).Create(testUpdateEntity)

然后在检测到冲突后应该自行将版本更新为2.

  • 我不想提及每列都有DoUpdates,因为实际表有多列.
  • 这是否是未处理带有条款的乐观锁定行为的情况?

推荐答案

据我所知,SEARCH目前不支持在使用OnConflict条款时自动更新乐观锁版本列.

当您将OnConflict Clause与UpdateAll一起使用时,SERM会生成一个UPSERT声明,该声明try 插入新行,如果发生冲突,它会使用新行的值更新现有行的所有列.然而,在这种情况下,SEARCH不会自动处理乐观锁版本列.

要在这种情况下处理乐观锁版本列,您可以使用DoUpdate Claude显式指定要更新的列.

由于您提到您的表有多个列,并且您不想显式列出所有列,请try 下面的代码来动态生成列列表

// Define a function to get a list of columns to update excluding primary key and version
func getColumnsToUpdate(db *gorm.DB, entity interface{}) ([]string, error) {
    var columnsToUpdate []string

    // Retrieve table name
    tableName := db.NamingStrategy.TableName("", db.Statement.Schema.Table)

    // Retrieve column names
    columnNames, err := db.Migrator().Columns(tableName)
    if err != nil {
        return nil, err
    }

    // Exclude primary key and version columns
    for _, columnName := range columnNames {
        if columnName != "ID" && columnName != "Version" {
            columnsToUpdate = append(columnsToUpdate, columnName)
        }
    }

        return columnsToUpdate, nil
    
    }

然后更新您的查询

// Define update data
updateData := make(map[string]interface{})
for _, column := range columnsToUpdate {
    updateData[column] = "updated_value" // Set your updated value here
}

// Add version update
updateData["Version"] = gorm.Expr("Version + 1")

// Apply update with OnConflict clause
dres := u.db.WithContext(context.TODO()).Clauses(clause.OnConflict{
    UpdateAll: true,
}).Model(&TestEntity{}).Where("id = ?", testUpdateEntity.ID).Updates(updateData)

我希望这将有助于

Go相关问答推荐

如何在使用中介资源时处理函数中的`defer`

GORM Find方法中缺少字段

即使HTTP服务器正在使用GO和Protobuf、SQL Server启动,请求也不返回结果

如何用Golang解码这个嵌套的json?

从使用Golang otelmux检测的Otel跟踪中获取trace_id

从MySQL/GO表获取行数据

优化方式中所有可能组合的字符串相似度

htmx 表单 + gin 无法正确读取请求正文

以编程方式取消 pyspark dataproc 批处理作业(job)

是否可以在 hyperledger-chaincode 中使用 gRPC?如果可以,我如何避免在测试网络上调用时出错?

io.Reader 无限循环与 fmt.Fscan

从单词中删除特殊字符

如何从 Asterisk Manager Interface Event 获取活动呼叫数

不能使用 mockDB(*MockDB 类型的变量)作为 struct 文字中的 *gorm.DB 值

Golang计算 struct struct 中的字段数

将接口方法的参数限制为几个允许的 struct ?

Golang Echo Labstack 如何在模板视图中调用函数/方法

使用 LoadLibraryA(path_to_dll) 加载 DLL 会将文件描述符 0、1 和 2 的继承句柄标志 (HANDLE_FLAG_INHERIT) 从 1 更改为 0

如何访问Go 1.18泛型 struct (structs)中的共享字段

在 etcd 键值存储中禁用历史记录