go语言项目--实例化(图书管理)--004

发布时间:2026/7/11 14:39:51

go语言项目--实例化(图书管理)--004
v4: 并发借书系统 — 安全与并发一、版本概述v4 在 v3 的 HTTP API 基础上引入了借阅系统和并发控制。核心挑战是多人同时借同一本书时的库存超卖问题通过sync.Mutexcontext.Context超时控制解决。还引入了优雅关闭和定时逾期检查。相比 v3 的核心变化借阅系统BorrowRecord 模型 BorrowService BorrowRepository并发安全Mutex 加锁防止超借Context 超时控制借阅操作库存分离Book 新增 TotalStock/Available 字段借阅扣减 Available优雅关闭signal.Notify http.Server.Shutdown定时任务StartOverdueChecker 每 30 秒检查逾期项目结构v4/ ├── main.go # 入口优雅关闭定时任务 ├── model/ │ ├── book.go # Book 增加 TotalStock/Available │ └── borrow_record.go # 借阅记录新增 ├── repository/ │ ├── book_repo.go # 增加 DecreaseAvailable/IncreaseAvailable │ └── borrow_repo.go # 借阅仓储新增 ├── service/ │ ├── book_service.go # 图书业务 │ └── borrow_service.go # 借阅业务并发控制新增核心 ├── handler/ │ └── http_handler.go # 新增借阅路由 ├── middleware/ │ └── logger.go # 日志恢复 └── data/ ├── books.json └── borrows.json二、核心代码解读关键片段borrow_record.go — 借阅模型const(StatusBorrowedborrowedStatusReturnedreturnedStatusOverdueoverdueOverdueDays15)typeBorrowRecordstruct{IDintjson:idBookIDintjson:book_idBookTitlestringjson:book_titleUserNamestringjson:user_nameBorrowDate time.Timejson:borrow_dateReturnDate*time.Timejson:return_date,omitemptyStatusstringjson:statusIsOverduebooljson:is_overdue}设计要点状态机borrowed → returned / overdueReturnDate使用指针*time.Time零值时序列化为 null 而非零时间OverdueDays 15作为逾期阈值borrow_service.go — 并发借阅核心typeborrowServicestruct{repo*repository.BorrowRepository bookRepo*repository.BookRepository mu sync.Mutex}func(s*borrowService)BorrowBook(ctx context.Context,bookIDint,userNamestring)(*model.BorrowRecord,error){// 1. 加锁 — 防止并发超借s.mu.Lock()defers.mu.Unlock()// 2. Context 超时检查select{case-ctx.Done():returnnil,ctx.Err()default:}// 3. 检查库存book,err:s.bookRepo.GetBookByID(bookID)iferr!nil{returnnil,err}ifbook.Available0{returnnil,ErrBookNotAvailable}// 4. 扣减库存iferr:s.bookRepo.DecreaseAvailable(bookID);err!nil{returnnil,err}// 5. 创建借阅记录失败时回滚库存record,err:s.repo.AddRecord(bookID,book.Title,userName)iferr!nil{s.bookRepo.IncreaseAvailable(bookID)// 回滚returnnil,err}returnrecord,nil}设计要点Mutex 加锁同一时刻只有一个借阅操作进入临界区防止读到库存为1 → 两个请求都通过的超卖Context 超时Handler 层设置context.WithTimeout5秒超时自动取消补偿事务创建记录失败时调用IncreaseAvailable回滚库存锁粒度使用全局 Mutex简化实现v5 会升级为分布式锁main.go — 优雅关闭// 监听系统信号quit:make(chanos.Signal,1)signal.Notify(quit,syscall.SIGINT,syscall.SIGTERM)// 优雅关闭-quit fmt.Println(\n 正在关闭服务...)cancel()// 取消定时任务ctx,shutdown:context.WithTimeout(context.Background(),5*time.Second)defershutdown()srv.Shutdown(ctx)// 等待现有请求完成StartOverdueChecker — 定时任务func(s*borrowService)StartOverdueChecker(ctx context.Context){ticker:time.NewTicker(30*time.Second)gofunc(){for{select{case-ticker.C:s.checkAndUpdateOverdue()case-ctx.Done():ticker.Stop()return}}}()}三、与 v3 的对比特性v3v4业务范围仅图书管理图书借阅并发控制无Mutex Context库存模型无TotalStock/Available优雅关闭无signal Shutdown定时任务无Ticker select错误恢复middlewaremiddleware 补偿事务四、设计思想思想体现并发安全Mutex 保护共享状态防止竞态条件超时控制Context 传播取消信号防止操作阻塞补偿事务失败时回滚已执行的操作保证数据一致性优雅关闭收到信号后等待请求完成避免数据丢失定时任务Ticker select ctx.Done() 可取消的循环五、为什么需要 v5v4 实现了并发借阅但存在架构级限制单进程所有功能在一个进程中无法独立扩缩容内存存储重启丢失数据虽然会保存到文件但不适合生产全局锁Mutex 只能保护单进程内的并发多实例部署无效无缓存每次查询都从文件读取性能受限服务间强耦合BookService 和 BorrowService 在同一进程v5 的改进方向微服务拆分 MySQL 持久化 Redis 缓存/分布式锁 gRPC 通信。##六、补充内容v4 API 测试指南 一、启动服务bashcdH:/libraries-pm/go-library go run ./v4 服务启动后默认监听 http://localhost:8080 二、API 列表 方法 路径 功能 分类 POST /books 添加图书 图书管理 GET /books 查询所有图书 图书管理 GET /books/{id}查询单本图书 图书管理 PUT /books/{id}更新图书 图书管理 DELETE /books/{id}删除图书 图书管理 POST /books/save 保存到文件 图书管理 POST /books/{id}/borrow 借书 借阅管理v4新增 POST /books/{id}/return 还书 借阅管理v4新增 GET /books/{id}/status 查询图书状态 借阅管理v4新增 GET /borrows 借阅历史 借阅管理v4新增 GET /health 健康检查 系统 三、测试步骤3.1健康检查bashcurlhttp://localhost:8080/health 期望返回 json{code:0,message:success,data:{status:ok,version:v4.0}}3.2添加图书含库存bash# 添加一本库存为3的图书curl-XPOST http://localhost:8080/books\-HContent-Type: application/json\-d{title:Go并发实战,author:张三,price:69.00,stock:3}期望返回 json{code:0,message:success,data:{id:1,title:Go并发实战,author:张三,price:69,total_stock:3,available:3}}3.3查询所有图书bashcurlhttp://localhost:8080/books3.4用户A借书bashcurl-XPOST http://localhost:8080/books/1/borrow\-HContent-Type: application/json\-d{user_name:张三}期望返回库存从3变为2 json{code:0,message:success,data:{id:1,book_id:1,book_title:Go并发实战,user_name:张三,status:borrowed,...}}3.5用户B借书同一本书bashcurl-XPOST http://localhost:8080/books/1/borrow\-HContent-Type: application/json\-d{user_name:李四}3.6查询图书状态bashcurlhttp://localhost:8080/books/1/status 期望返回显示库存和借阅情况 json{code:0,message:success,data:{id:1,title:Go并发实战,total_stock:3,available:1,borrowed_count:2,borrow_records:[...]}}3.7用户A还书bashcurl-XPOST http://localhost:8080/books/1/return\-HContent-Type: application/json\-d{user_name:张三}期望返回 json{code:0,message:success,data:{message:还书成功}}3.8查询借阅历史bash# 查询某本书的借阅历史curlhttp://localhost:8080/borrows?book_id1# 查询逾期记录不传参数默认返回逾期curlhttp://localhost:8080/borrows 四、并发测试v4 核心功能4.1模拟100人抢1本书bash# 1. 先添加一本库存为1的图书curl-XPOST http://localhost:8080/books\-HContent-Type: application/json\-d{title:限量版图书,author:测试,price:99.00,stock:1}# 2. 使用脚本并发借书Linux/Macforiin{1..100};docurl-XPOST http://localhost:8080/books/2/borrow\-HContent-Type: application/json\-d{\user_name\:\user$i\}donewait# 3. 查询状态确认只有1人借到curlhttp://localhost:8080/books/2/status4.2Windows 并发测试使用 PowerShell powershell# 在 PowerShell 中执行1..100|ForEach-Object{$body{user_nameuser$_}|ConvertTo-Json Invoke-RestMethod-Urihttp://localhost:8080/books/2/borrow-MethodPOST-Body$body-ContentTypeapplication/json}|Measure-Object 五、竞态检测bash# 使用 -race 检测数据竞争gotest-race./v4/... 六、完整测试脚本bash#!/bin/bashechoecho v4 API 测试echoecho-e\n1️⃣ 健康检查curl-shttp://localhost:8080/health|jq.echo-e\n2️⃣ 添加图书库存3本curl-s-XPOST http://localhost:8080/books\-HContent-Type: application/json\-d{title:Go并发实战,author:张三,price:69.00,stock:3}|jq.echo-e\n3️⃣ 查询所有图书curl-shttp://localhost:8080/books|jq.echo-e\n4️⃣ 张三借书curl-s-XPOST http://localhost:8080/books/1/borrow\-HContent-Type: application/json\-d{user_name:张三}|jq.echo-e\n5️⃣ 李四借书curl-s-XPOST http://localhost:8080/books/1/borrow\-HContent-Type: application/json\-d{user_name:李四}|jq.echo-e\n6️⃣ 图书状态curl-shttp://localhost:8080/books/1/status|jq.echo-e\n7️⃣ 张三还书curl-s-XPOST http://localhost:8080/books/1/return\-HContent-Type: application/json\-d{user_name:张三}|jq.echo-e\n8️⃣ 再次查询状态curl-shttp://localhost:8080/books/1/status|jq.echo-e\n9️⃣ 借阅历史curl-shttp://localhost:8080/borrows?book_id1|jq.echo-e\n✅ 测试完成七、测试要点总结 测试场景 预期结果 验证方法 正常借书 库存减1生成借阅记录 查看返回数据 库存不足时借书 返回错误 库存不足 查看错误信息100人抢1本书 仅1人成功99人失败 查看状态available0正常还书 库存加1记录状态变更 查询状态 不存在的用户还书 返回错误 未找到借阅记录 查看错误信息 逾期检查 日志打印逾期记录 观察服务端日志

相关新闻

Ceph网络配置开发详解:openeuler/ceph_dev中网络架构与优化指南

Ceph网络配置开发详解:openeuler/ceph_dev中网络架构与优化指南

2026/7/11 14:39:50

Ceph网络配置开发详解:openeuler/ceph_dev中网络架构与优化指南 【免费下载链接】ceph_dev ceph_dev is a project focus on some feature developing based on ceph 项目地址: https://gitcode.com/openeuler/ceph_dev 前往项目官网免费下载:htt…

生鲜避坑农残焦虑:自有园区优势及顽虎适合谁吃

生鲜避坑农残焦虑:自有园区优势及顽虎适合谁吃

2026/7/9 20:33:37

生鲜选购避坑指南:理性看待农残焦虑与自有园区模式的价值在消费升级的大背景下,注重饮食安全的消费者在生鲜选购时,往往将核心关注点聚焦于农药残留与化学制剂的使用情况。面对市场上种类繁多的蔬菜品牌,单纯依赖外观判断已难以满…

C++双目运算符+=的重载详解

C++双目运算符+=的重载详解

2026/7/8 11:44:40

1、重载12345678910111213141516171819202122232425262728293031class Complex{public:Complex(int a, int b): _a(a), _b(b){}Complex& operator (Complex& other){this->_a other._a;this->_b other._b;return *this;}void print(){cout << _a <<…

怎样快速下载网页视频:免费开源插件VideoDownloadHelper的完整指南

怎样快速下载网页视频:免费开源插件VideoDownloadHelper的完整指南

2026/7/11 14:32:59

怎样快速下载网页视频&#xff1a;免费开源插件VideoDownloadHelper的完整指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否遇到过这…

GitHub Desktop汉化终极指南:3分钟实现中文界面自由

GitHub Desktop汉化终极指南:3分钟实现中文界面自由

2026/7/11 14:32:59

GitHub Desktop汉化终极指南&#xff1a;3分钟实现中文界面自由 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 【GitHub桌面客户端中文汉化】 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop的…

GitHub Desktop汉化终极指南:5分钟让Git客户端变中文

GitHub Desktop汉化终极指南:5分钟让Git客户端变中文

2026/7/11 14:32:59

GitHub Desktop汉化终极指南&#xff1a;5分钟让Git客户端变中文 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 【GitHub桌面客户端中文汉化】 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 还在为GitHub Desktop的…

Unblob:终极二进制容器文件解析工具完全指南

Unblob:终极二进制容器文件解析工具完全指南

2026/7/11 14:32:59

Unblob&#xff1a;终极二进制容器文件解析工具完全指南 【免费下载链接】unblob Extract files from any kind of container formats 项目地址: https://gitcode.com/gh_mirrors/un/unblob 在数字取证、固件分析和逆向工程领域&#xff0c;处理复杂的二进制容器文件一直…

arXiv热点论文:3B/7B小模型在医疗事实核查中反超GPT-4o/GPT-5

arXiv热点论文:3B/7B小模型在医疗事实核查中反超GPT-4o/GPT-5

2026/7/11 14:32:59

开篇总结 这篇论文是一项针对生物医药领域断言验证&#xff08;Claim Verification&#xff09;的突破性研究 。作者通过 QLoRA 技术微调了 Phi-3、Qwen2.5 和 Mistral 等 3B 到 7B 的轻量级开源大模型 &#xff0c;结果发现&#xff0c;仅用 1008 条训练样本&#xff0c;7B 小…

5大核心功能解密:digiCamControl如何让你的DSLR相机变身智能工作站

5大核心功能解密:digiCamControl如何让你的DSLR相机变身智能工作站

2026/7/11 14:22:59

5大核心功能解密&#xff1a;digiCamControl如何让你的DSLR相机变身智能工作站 【免费下载链接】digiCamControl DSLR camera remote control open source software 项目地址: https://gitcode.com/gh_mirrors/di/digiCamControl 你是否曾经在拍摄产品静物时&#xff0c…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/10 22:32:48

解锁AMD Ryzen处理器深层性能&#xff1a;SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述&#xff1a;6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下&#xff0c;AI工程师岗位需求同比增长217%&#xff08;LinkedIn数据&#xff09;。不同于传统算法工程师需要3-5年培养周期&#xff0c;现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/10 6:57:56

1. 项目背景与核心价值在计算机视觉领域&#xff0c;YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备&#xff08;如树莓派、Jetson Nano或手机终端&#xff09;时&#xff0c;立刻会遇到两个致命问题&#xff1a;模型体积庞大&#xff08;原始YO…

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

2026/7/11 0:02:03

WechatDecrypt技术解析&#xff1a;深入理解微信数据库AES-256-CBC解密机制 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 在数字隐私日益重要的今天&#xff0c;微信聊天记录作为个人数字资产的重要组成…

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

2026/7/11 0:02:03

5分钟搞定Kodi字幕难题&#xff1a;智能字幕插件让你追剧无忧 &#x1f3ac; 【免费下载链接】zimuku_for_kodi Kodi 插件&#xff0c;用于从「字幕库」网站下载字幕 项目地址: https://gitcode.com/gh_mirrors/zi/zimuku_for_kodi 还记得那个深夜吗&#xff1f;你刚下载…

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

2026/7/11 0:02:03

PostgreSQL 备份与恢复实战&#xff1a;从 pg_dump 到时间点恢复的生产级方案 一、数据库备份最容易被忽略的问题&#xff0c;不是「有没有做备份」&#xff0c;而是「备份能不能恢复、恢复要多久、以及恢复后的数据对不对」 很多团队做数据库备份的方式是「写个 cron job&am…