知识点整理 | 豆包MarsCode AI刷题
知识点整理自字节跳动后端青训营的网课
数据库
事务
事务引擎实现了数据库的ACID能力,这里还是以MySQL的InnoDB为例来介绍数据库内部是通过哪些技术来实现ACID
- Atomicity:InnoDB中通过undo日志实现了数据库的原子性,通过Undo Log,数据库可以回滚到事务开始的状态;
- Isolation:通过Undo Log实现MVCC(多版本并发控制),降低读写冲突。
- Durability:通过Redo Log(一种WAL实现方式)来保证事务在提交后一定能持久化到磁盘中。
- Consistency:一致性本质上是一种业务层的限制。
关系型数据库的通用组件
- Query Engine: 负责解析query,生成查询计划
- Txn(Transaction) Manager: 负责事务并发管理
- Lock Manager: 负责锁相关的策略
- Storage Engine: 负责组织内存/磁盘数据结构
- Replication: 负责主备同步
并发更新字段
// 并发不安全
var row Model
db.Where(&Model{Id: req.Id}).First(&row)
db.Where("id = ?", row.Id).Update("value", row.Valie + req.Value)
// 并发安全
db.Where("id = ?", req.Id).
UpdateColumn("value", gorm.Expr("quantity + ?", req.Value))
前者会将数据获取到应用层,然后再更新,在这期间可能有其他请求将值修改,引发数据竞争。后者在数据库内加法操作,避免了可能的数据竞争问题,后者的SQL写法:
UPDATE table SET value = value + ? Where id = ?
使用gorm与数据库交互
获取gorm框架
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
连接数据库
DB, err := gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN),&gorm.Config{})
使用自动迁移创建表
err := DB.AutoMigrate(&model)
一些细节
其他CRUD操作细节可查官网文档
First查找不到单条数据会返回ErrRecordNotFound,而Find查找多条数据,查找不到时不会返回错误。结构体作为查询条件时,0和False不会作为查询条件,此时应用map[string]interface{}代替,更新操作也是类似。
// SELECT * FROM products WHERE name = "t-shirt";
db.Where(&Product{Name: "t-shirt", Tag: 0}).Find(&producters)
// SELECT * FROM products WHERE name = "t-shirt" AND tag = 0;
db.Where(map[string]interface{}{"Name": "t-shirt", "Tag": 0}).Find(&producters)
在有gorm.DeleteAt的表中实现硬删除使用Unscoped
层次结构
Hertz代码生产工具产生的文件树:
.
|-- biz
| |-- dal
| |-- handler
| |-- router
| |-- service
| `-- utils
|-- conf
| |-- conf.go
| |-- dev
| |-- online
| `-- test
|-- hertz_gen
| |-- api
| `-- frontend
biz(business)业务层
由浅入深:web -> router -> handler -> service -> dal
router处理路由,可添加中间件,如登陆和鉴权等。handler接收并解析前端发来的HTTP请求,可添加重定向、返回参数封装等功能service使用RPC客户端调用对应微服务。微服务内的service存有具体业务处理逻辑。dal(data layer)数据层内有MySQL和Redis的访问客户端,负责与对应的数据库做数据交互
conf配置文件
dev、test和online分别对应开发、测试和线上三种开发环境,实际通过设置系统环境变量GO_ENV来区分。
hertz_gen
Hertz为生成的脚手架代码
开发过程遇到的些问题
导入问题
"github.com/YiD11/gomall/rpc_gen/kitex_gen/product"
"github.com/YiD11/gomall/app/frontend/hertz_gen/frontend/product"
两条路径分别导入kitex框架生成和Hertz框架生成的代码,实际在开发过程中确有遇到过VS Code导入错误的情况。
replace (
github.com/path/to/gomall/rpc_gen => ../../rpc_gen
)
rpc_gen存有Kitex生成的RPC框架的脚手架代码。若根包名为github.com/path/to/gomall,如果远端还未存有对应rpc_gen的代码,则需要在go.mod中指定本地库,否则会出现找不到库。