035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

  今天在看同事程序的时候,看到这种用法,顺便学习下。

一:理论

1.功能

  这个功能是上锁。

  上的是一个排它锁,也就是说,其他的事务是可以读取的。但是不能写入或者更新。

二:实践

1.创建表

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

2.提交一条记录

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

3.将自动提交关闭

  然后插入一条数据。

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

4.再启动一个客户端,进行查询

  会发现,这里的值被查询出来还是10,因为没有提交。

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

5.操作人员2发现数据不对,然后发起修改。

  但由于会话1中对该行记录的修改未提交,所以,排它锁并没有释放,因而操作人员2发起的这个修改操作会等待,直至会话1释放该锁(提交或回滚)。

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

6.然后会话1进行提交,并查询

  这个时候,结果是对的。

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

7.提交会话2的修改

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

8.再次查询结果

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

三:解决方式

1.解决方式

  在我们试图修改某个记录时,先利用select ... from xxx where zzz for update;将该记录加锁。这样,就可以确保我现在看到的值,一定不会再被其他人修改了。

2.会话1

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

3.会话2

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

4.等会话1commit了

  会将结果查询出来。

  035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

5.再进行提交

  这个时候,会在最新的基础上进行新增。

  与刚才的区别:

  这个查询的结果,是15,而刚才的查询结果确是10.

  因为这里有一段时间再等待,这个行记录被锁定。

四:需要注意的地方

1.是否根据主键决定是否锁表

  选中某一个行的时候,如果是通过主键id选中的。那么这个时候是行级锁。 其他的行还是可以直接insert 或者update的。
  如果是通过其他的方式选中行,或者选中的条件不明确包含主键。这个时候会锁表。其他的事务对该表的任意一行记录都无法进行插入或者更新操作。只能读取。

上一篇:使用CSS3滤镜让图片反转颜色


下一篇:C#开发系统服务时用的定时器组件