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 排他锁

posted @ 2019-11-03 23:21  jssyjam  阅读(6977)  评论(0编辑  收藏  举报