本节核心内容
- 介绍了为什么要使用事物
- 介绍事物对象的常用方法
- 介绍事物的应用场景
- 介绍事物的ACID
- 演示了事物的示例代码
- 介绍开发中需要注意的点
本小节视频教程和代码:百度网盘
可先下载视频和源码到本地,边看视频边结合源码理解后续内容,边学边练。
事务(transaction)
事物:保持逻辑数据一致性与可恢复性,必不可少的利器!
为什么要使用事务
银行转账是经典的解释事务的例子,如:用户A给用户B转账5000元主要步骤可以概括为以下几步:
-
检测A账户余额 > 5000元
-
A账户余额减去 5000元
-
B账户余额增加 5000元
这几步要么都成功,要么一个都不成功,否则都会导致数据不一致(5000元不翼而飞)。这就可以用到事务来保证,如果是不同银行之间的转账还需要用到分布式事务。
事物对象的常用方法
Tx, err := Db.Begin()
开启事务Tx.Exec()
执行事务Tx.Commit()
提交事务Tx.Rollback()
回滚事务Tx.Query()
查询语句Tx.QueryRow()
查询语句,但只返回一行
事务的应用场景
-
1. 同时更新多个表
-
2. 同时更新多行数据
事务的ACID
-
1. 原子性
一个事务的执行被视为一个不可分割的最小单元。事务里面的操作,要么全部成功执行,要么全部失败回滚。
-
2. 一致性
事务结束的时候,所有的内部数据都是正确的。
-
3. 隔离性
并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
-
4. 持久性
事务提交之后,数据是永久性的,不可再回滚。
示例代码
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func Transaction(db *sql.DB) {
// 开启事务
tx, err := db.Begin()
if err != nil {
panic(err)
}
result, err := tx.Exec("insert into user(name, age)values(?,?)", "Jack", 98)
if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
}
fmt.Println("result", result)
exec, err := tx.Exec("update user set name=?, age=? where id=?", "Jack", 98, 1)
if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
}
fmt.Println("exec", exec)
// 提交事务
err = tx.Commit()
if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
}
}
func main() {
dns := "root:root@tcp(127.0.0.1:3306)/test"
db, err := sql.Open("mysql", dns)
if err != nil {
panic(err)
}
err = db.Ping()
if err != nil {
panic(err)
}
Transaction(db)
}
需要注意的点
- 执行失败要回滚
- 提交失败要回滚
小结
本小节主要讲了事物对象的常用方法和事物的应用场景,以及在开发中需要注意的点
请发表评论