1. 首页>
  2. 技术文章>
  3. mysql并发的处理

mysql并发的处理

8/18/22 2:13:34 PM 浏览 1350 评论 0

mysql

当我们使用for update的时候,如果在事务中的话,则另一个事务也用到这个表的数据,且用了for update的话,则必须等待上一个事务执行完毕。且下一个事务拿到的为上个事务执行成功后的值。

比如代码片段A:

_repository.UseTran(() =>{
      var trace = _repository.Queryable<BasLog>().Where(p => p.Id == 2208021736122010).OrderBy(p => p.Id).With(SqlWith.UpdLock).First();
      trace.AddTime = DateTime.Now;
      _repository.Update<BasLog>(trace);
});

如果这个没有commit的话,这个时候执行代码片段B:

start TRANSACTION;
select * from bas_log where id = 2208021736122010 for update;
commit;

会发现一直卡住,没有出来结果,当A执行commit后,B出来结果,且B的结果为A执行后的最新数据。且在A中,因为这个查询是主键查询,所以并不会锁中整张表,只会锁一行。有些时候,mysql认为走全表扫描的速度会更快,那么即使用了索引也还是会锁住全表,需要强制使用索引,比如:

select * from bas_article force index(name) where name = '52jiagou.com'

而且也不用担心update语句会锁表,因为update语句会将其转换成主键索引。如果锁的行数比较多,确实有影响则可以用版本号的方式去解决,就是:表中增加版本号字段,然后每次更新都+1,查出数据的时候得到版本号,然后更新的时候同时更新版本号,条件版本号=旧的版本号,根据修改的行数来确定是否真的修改成功。

网友讨论