添加对Gorm写入的操作锁繁殖

This commit is contained in:
sysnix 2023-09-25 03:32:37 +08:00
parent 3ae1f0a625
commit eeec5453ae
8 changed files with 58 additions and 102 deletions

View File

@ -1,38 +0,0 @@
package async
import (
"blog/internal/consts"
"blog/internal/model/blog"
"blog/third_party/database"
"context"
"log"
"math"
"time"
"github.com/redis/go-redis/v9"
)
var articleChannel chan string
func init() {
f := math.Pow(2, 5)
articleChannel = make(chan string, int(f))
go func() {
ctx := context.Background()
for id := range articleChannel {
log.Println(id)
time := time.Now().UnixMilli()
var article *blog.BlogArticle
database.GormTemplate.Table("blog_articles").Where("id = ?", id).UpdateColumn("publish_time", time)
database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(article)
database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: article})
}
}()
}
func PublishArticle(id string) {
articleChannel <- id
}

View File

@ -1,33 +0,0 @@
package async
import (
"blog/internal/consts"
"blog/internal/model/blog"
"blog/third_party/database"
"context"
"math"
"github.com/redis/go-redis/v9"
)
var diaryChannel chan string
func init() {
f := math.Pow(2, 5)
diaryChannel = make(chan string, int(f))
go func() {
ctx := context.Background()
for id := range diaryChannel {
// log.Println(id)
var diary blog.BlogDiary
database.GormTemplate.Table("blog_diaries").Where("id = ?", id).First(&diary)
database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(diary.PublishTime), Member: diary})
}
}()
}
func PublishDiary(id string) {
diaryChannel <- id
}

View File

@ -8,6 +8,7 @@ import (
"math" "math"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm"
) )
var viewRecordChannel chan ViewRecord var viewRecordChannel chan ViewRecord
@ -25,14 +26,20 @@ func init() {
viewRecordChannel = make(chan ViewRecord, int(f)) viewRecordChannel = make(chan ViewRecord, int(f))
go func() { go func() {
ctx := context.Background()
for record := range viewRecordChannel { for record := range viewRecordChannel {
log.Println("IP:", record.IpAddr, "点击了:", record.Title) log.Println("IP:", record.IpAddr, "点击了:", record.Title)
relId := record.RelId relId := record.RelId
record.Id = uuid.NewString() record.Id = uuid.NewString()
database.GormTemplate.Table("blog_view_record").Create(&record) database.WGorm().Transaction(func(tx *gorm.DB) error {
ctx := context.Background() err := tx.Table("blog_view_record").Create(&record).Error
database.RedisTemplate.HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, relId, 1) if err != nil {
return err
}
err2 := database.RedisTemplate.HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, relId, 1).Err()
return err2
})
database.WGormUnlock()
} }
}() }()

View File

@ -1,18 +1,20 @@
package admin package admin
import ( import (
"blog/internal/async" "blog/internal/consts"
"blog/internal/model/AjaxResult" "blog/internal/model/AjaxResult"
"blog/internal/model/admin" "blog/internal/model/admin"
"blog/internal/model/vo" "blog/internal/model/vo"
"blog/third_party/SessionUtil"
"blog/third_party/database" "blog/third_party/database"
"context"
"strings" "strings"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/kataras/iris/v12" "github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/sessions" "github.com/kataras/iris/v12/sessions"
"github.com/mitchellh/mapstructure" "github.com/redis/go-redis/v9"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -29,18 +31,16 @@ func (ctrl *DiaryController) Get() {
} }
func (ctrl *DiaryController) PostSubmit() { func (ctrl *DiaryController) PostSubmit() {
session := sessions.Get(ctrl.Ctx) user := SessionUtil.GetUser(ctrl.Session)
var userMap map[string]string
session.Decode("user", &userMap)
var user admin.SysUser
mapstructure.Decode(userMap, &user)
userId := user.Id userId := user.Id
content := ctrl.Ctx.FormValue("content") content := ctrl.Ctx.FormValue("content")
var err error var err error
ctx := context.Background()
diaryId := uuid.NewString() diaryId := uuid.NewString()
database.GormTemplate.Transaction(func(tx *gorm.DB) error { database.WGorm().Transaction(func(tx *gorm.DB) error {
now := time.Now().UnixMilli() now := time.Now().UnixMilli()
diary := admin.AdminDiary{Id: diaryId, PublishTime: now, Del: 0, CreateTime: now, CreateBy: userId} diary := admin.AdminDiary{Id: diaryId, PublishTime: now, Del: 0, CreateTime: now, CreateBy: userId}
ctn := vo.CommonContent{Id: uuid.NewString(), RelId: diaryId, Content: content} ctn := vo.CommonContent{Id: uuid.NewString(), RelId: diaryId, Content: content}
@ -80,11 +80,18 @@ func (ctrl *DiaryController) PostSubmit() {
if err != nil { if err != nil {
return err return err
} }
return nil
// database.GormTemplate.Table("blog_diaries").Where("id = ?", id).First(&diary)
err = database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(diary.PublishTime), Member: &diary}).Err()
if err != nil {
return err
}
err = database.RedisTemplate.Set(ctx, consts.REDIS_BLOG_CONTENT+diaryId, content, time.Duration(0)).Err()
return err
}) })
defer database.WGormUnlock()
if err != nil { if err != nil {
async.PublishDiary(diaryId)
ctrl.Ctx.JSON(AjaxResult.OkMsg("发布成功", nil)) ctrl.Ctx.JSON(AjaxResult.OkMsg("发布成功", nil))
return return
} }

View File

@ -67,12 +67,13 @@ func (ctrl *FileController) PostUpload() {
Data: bytes, State: "1", Data: bytes, State: "1",
Del: 0, Del: 0,
} }
err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { err = database.WGorm().Transaction(func(tx *gorm.DB) error {
err2 := tx.Table("common_files").Create(sysFile).Error err2 := tx.Table("common_files").Create(sysFile).Error
return err2 return err2
// log.Println(sysFile) // log.Println(sysFile)
// return nil // return nil
}) })
defer database.WGormUnlock()
if err != nil { if err != nil {
// { // {
// success : 0 | 1, // 0 表示上传失败1 表示上传成功 // success : 0 | 1, // 0 表示上传失败1 表示上传成功
@ -98,7 +99,7 @@ func (ctrl *FileController) DelFile() {
return return
} }
ctx := context.Background() ctx := context.Background()
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error { err := database.WGorm().Transaction(func(tx *gorm.DB) error {
txErr := tx.Table("common_files").Delete(&vo.CommonFiles{Id: id}).Error txErr := tx.Table("common_files").Delete(&vo.CommonFiles{Id: id}).Error
if txErr != nil { if txErr != nil {
return txErr return txErr
@ -107,6 +108,7 @@ func (ctrl *FileController) DelFile() {
return txErr return txErr
}) })
defer database.WGormUnlock()
if err != nil { if err != nil {
ctrl.Ctx.JSON(AjaxResult.Error("删除失败")) ctrl.Ctx.JSON(AjaxResult.Error("删除失败"))

View File

@ -96,7 +96,7 @@ func (*articleService) CreateArticle(articel *admin.AdminArticle) (string, error
articel.Del = 0 articel.Del = 0
articel.State = consts.ARTICLE_STATE_DRAFT articel.State = consts.ARTICLE_STATE_DRAFT
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error { err := database.WGorm().Transaction(func(tx *gorm.DB) error {
contentId := uuid.NewString() contentId := uuid.NewString()
content := articel.Content content := articel.Content
commonContent := vo.CommonContent{Id: contentId, RelId: articleId, Content: content, State: "down"} commonContent := vo.CommonContent{Id: contentId, RelId: articleId, Content: content, State: "down"}
@ -108,6 +108,7 @@ func (*articleService) CreateArticle(articel *admin.AdminArticle) (string, error
err = tx.Table("blog_articles").Create(*articel).Error err = tx.Table("blog_articles").Create(*articel).Error
return err return err
}) })
defer database.WGormUnlock()
return articleId, err return articleId, err
} }
@ -115,7 +116,7 @@ func (*articleService) UpdateArticle(articel *admin.AdminArticle) (string, error
time := time.Now().UnixMilli() time := time.Now().UnixMilli()
articleId := articel.Id articleId := articel.Id
articel.UpdateTime = time articel.UpdateTime = time
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error { err := database.WGorm().Transaction(func(tx *gorm.DB) error {
//更新Article //更新Article
tx.Table("blog_articles").Updates(articel) tx.Table("blog_articles").Updates(articel)
@ -123,6 +124,7 @@ func (*articleService) UpdateArticle(articel *admin.AdminArticle) (string, error
err := tx.Table("common_contents").Where("rel_id", articleId).UpdateColumn("content", articel.Content).Error err := tx.Table("common_contents").Where("rel_id", articleId).UpdateColumn("content", articel.Content).Error
return err return err
}) })
defer database.WGormUnlock()
return articleId, err return articleId, err
} }
@ -142,12 +144,13 @@ func (*articleService) PublishArticle(id string) error {
article.PublishTime = now article.PublishTime = now
article.State = consts.ARTICLE_STATE_PUBLISH article.State = consts.ARTICLE_STATE_PUBLISH
err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { err = database.WGorm().Transaction(func(tx *gorm.DB) error {
var txErr error = tx.Table("blog_articles").Updates(&article).Error var txErr error = tx.Table("blog_articles").Updates(&article).Error
if txErr != nil { if txErr != nil {
return errors.New("文章更新错误") return errors.New("文章更新错误")
} }
txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_PUBLISH) // txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_PUBLISH)
txErr = tx.Table("common_contents").Where("rel_id = ?", id).UpdateColumn("state", consts.CONTENT_STATE_PUBLISH).Error
if txErr != nil { if txErr != nil {
return errors.New("文本状态更新错误") return errors.New("文本状态更新错误")
} }
@ -165,7 +168,7 @@ func (*articleService) PublishArticle(id string) error {
return txErr return txErr
}) })
defer database.WGormUnlock()
return err return err
} }
@ -180,7 +183,7 @@ func (*articleService) UnPublishArticle(id string) error {
return errors.New("撤下失败,文章状态不是已发布状态,无法撤下") return errors.New("撤下失败,文章状态不是已发布状态,无法撤下")
} }
err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { err = database.WGorm().Transaction(func(tx *gorm.DB) error {
var txErr error var txErr error
ctx := context.Background() ctx := context.Background()
txErr = database.RedisTemplate.ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, txErr = database.RedisTemplate.ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST,
@ -203,10 +206,12 @@ func (*articleService) UnPublishArticle(id string) error {
if txErr != nil { if txErr != nil {
return errors.New("文章状态更新错误") return errors.New("文章状态更新错误")
} }
txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_DOWN) // txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_DOWN)
txErr = tx.Table("common_contents").Where("rel_id = ?", id).UpdateColumn("state", consts.CONTENT_STATE_DOWN).Error
return txErr return txErr
}) })
defer database.WGormUnlock()
return err return err
} }
@ -214,10 +219,11 @@ func (*articleService) UnPublishArticle(id string) error {
func (*articleService) DelArticle(id string) error { func (*articleService) DelArticle(id string) error {
// articel := ArticleService.GetAdminArticle(id) // articel := ArticleService.GetAdminArticle(id)
// err := database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article).Error // err := database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article).Error
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error { err := database.WGorm().Transaction(func(tx *gorm.DB) error {
txErr := tx.Table("blog_articles").Where("id = ?", id).UpdateColumn("del", 1).Error txErr := tx.Table("blog_articles").Where("id = ?", id).UpdateColumn("del", 1).Error
return txErr return txErr
}) })
defer database.WGormUnlock()
return err return err
} }

View File

@ -18,13 +18,6 @@ import (
"github.com/kataras/iris/v12/sessions/sessiondb/redis" "github.com/kataras/iris/v12/sessions/sessiondb/redis"
) )
// func main() {
// i := time.Now().UnixMilli()
// log.Println(i)
// b, _ := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost)
// log.Println(string(b))
// }
func main() { func main() {
profile := os.Getenv("profile") profile := os.Getenv("profile")
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Ltime | log.Llongfile) log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Ltime | log.Llongfile)

View File

@ -3,12 +3,14 @@ package database
import ( import (
"log" "log"
"os" "os"
"sync"
"github.com/glebarez/sqlite" "github.com/glebarez/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
) )
var GormTemplate *gorm.DB var GormTemplate *gorm.DB
var rwMutex sync.RWMutex
func init() { func init() {
path := "./sqlite.db" path := "./sqlite.db"
@ -24,3 +26,13 @@ func init() {
log.Println("SQLite连接成功,Gorm初始化完成") log.Println("SQLite连接成功,Gorm初始化完成")
// db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{}) // db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
} }
// sqlite无法同时多个线程写入需要上锁保护读操作无需考虑
func WGorm() *gorm.DB {
rwMutex.Lock()
return GormTemplate
}
func WGormUnlock() {
rwMutex.Unlock()
}