35 lines
823 B
Go
35 lines
823 B
Go
package model
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
var ErrSessionNotFound = errors.New("会话不存在")
|
|
|
|
// CreateMessage 在会话行锁保护下分配消息序号,避免并发写入出现重复序号。
|
|
func CreateMessage(message *Message) error {
|
|
return DB.Transaction(func(tx *gorm.DB) error {
|
|
var session Session
|
|
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&session, message.SessionID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return ErrSessionNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
var maxSeq int
|
|
if err := tx.Model(&Message{}).
|
|
Where("session_id = ?", message.SessionID).
|
|
Select("COALESCE(MAX(seq), 0)").
|
|
Scan(&maxSeq).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
message.Seq = maxSeq + 1
|
|
return tx.Create(message).Error
|
|
})
|
|
}
|