Golang 并发、事务处理

  • 并发

Golang使用sync.WaitGroup来实现并发任务的同步:

sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。

方法注释
(wg *WaitGroup) Add(delta int)
计数器+delta
func (wg *WaitGroup) Done()
计数器-1
func (wg *WaitGroup) Wait()
阻塞直到计数器变为0

 

var wg sync.WaitGroup

wg.Add(1) // 启动一个goroutine就登记+1

go doDir()  //自定义函数处理业务逻辑

wg.Wait()  // 等待所有登记的goroutine都结束


func doDir(){

   defer wg.Done()  //goroutine结束就登记-1

}

goroutine是并发执行的,而goroutine的调度是随机的。

goroutine中最主要的是三个实体为GMP:

  • G代表一个goroutine对象,每次go调用的时候,都会创建一个G对象,它包括栈、指令指针以及对于调用goroutines很重要的其它信息,比如阻塞它的任何channel
  • P代表一个处理器,管理着一组goroutine队列,每一个运行的M都必须绑定一个P,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈地址及地址边界),P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间较长的goroutine暂停、运行后续的goroutine),当自己的队列消费完了就去全局队列里取,如果全局队列里也消费完了会去其他P的队列里抢任务。P的个数就是GOMAXPROCS(最大256),启动时固定的,一般不修改,每一个P保存着本地G任务队列,也有一个全局G任务队列。
  • M(machine)是Go运行时(runtime)对操作系统内核线程的虚拟,代表一个线程,每次创建一个M的时候,都会有一个底层线程创建, M与内核线程一般是一一映射的关系, 一个groutine最终是要放到M上执行的。

*注意 sync.WaitGroup是一个结构体,传递的时候要传递指针。

  • 事务

func execTransaction(db *sql.DB) error {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			tx.Rollback()
			return
		}
	}()
	err = execSql(tx)  //sql执行处理
	if err != nil {
		return err
	}
	return tx.Commit()
}

func execSql(tx *sql.Tx){
    var sqlCmd = fmt.Sprintf("insert into table values(...)")
    tx.Exec(sql)
}

注意 tx.Exec(sql) 而不是db.Exec(sql),否则就是两个连接,事务不起作用。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值