gorm 实现 mysql for update 排他锁

关于 MySQL 的排他锁网上已经有很多资料进行了介绍,这里主要是记录一下 gorm 如果使用排他锁。

排他锁是需要对索引进行锁操作,同时需要在事务中才能生效.具体操作如下:

假设有如下数据库表结构:

CREATE TABLE `employees` (
    `id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
    `name` varchar(64) NOT NULL COMMENT '雇员姓名',
    `age` TINYINT(5) NOT NULL COMMENT '雇员年龄',
    `addr` varchar(64) NOT NULL COMMENT '雇员家庭地址',
     PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='雇员信息表';

执行代码如下:

// Employee ...
type Employee struct {
    Name string `gorm:"column:name"`
    Age  int    `gorm:"column:age"`
    Addr string `gorm:"column:addr"`
}

// ForUpdateLock ...
func ForUpdateLock(db *gorm.DB, id int) error {
    // 创建事务
    tx := db.Begin()
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
        }
    }()

    var employee Employee
    if err := tx.Set("gorm:query_option", "FOR UPDATE").First(&employee, id).Error; err != nil {
        tx.Rollback()
        return err
    }
    // 此时指定 id 的记录被锁住.如果表中无符合记录的数据,则排他锁不生效
    // 执行其他数据库操作
    // ...
    if err := tx.Commit().Error; err != nil {
        tx.Rollback()
        return err
    }
    return nil
}

这里使用的主键索引来创建排他锁,也可以使用普通索引进行排他锁操作。

参考

issue

mysql innodb 排他锁

猜你喜欢

转载自www.cnblogs.com/jssyjam/p/11789863.html