添加对Gorm写入的操作锁繁殖
This commit is contained in:
parent
3ae1f0a625
commit
eeec5453ae
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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("删除失败"))
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
7
main.go
7
main.go
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue