關於 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
}
這里使用的主鍵索引來創建排他鎖,也可以使用普通索引進行排他鎖操作。