知识点整理 | 豆包MarsCode AI刷题

174 阅读3分钟

知识点整理 | 豆包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配置文件

devtestonline分别对应开发、测试和线上三种开发环境,实际通过设置系统环境变量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中指定本地库,否则会出现找不到库。