今天在看同事程序的时候,看到这种用法,顺便学习下。
一:理论
1.功能
这个功能是上锁。
上的是一个排它锁,也就是说,其他的事务是可以读取的。但是不能写入或者更新。
二:实践
1.创建表
2.提交一条记录
3.将自动提交关闭
然后插入一条数据。
4.再启动一个客户端,进行查询
会发现,这里的值被查询出来还是10,因为没有提交。
5.操作人员2发现数据不对,然后发起修改。
但由于会话1中对该行记录的修改未提交,所以,排它锁并没有释放,因而操作人员2发起的这个修改操作会等待,直至会话1释放该锁(提交或回滚)。
6.然后会话1进行提交,并查询
这个时候,结果是对的。
7.提交会话2的修改
8.再次查询结果
三:解决方式
1.解决方式
在我们试图修改某个记录时,先利用select ... from xxx where zzz for update;将该记录加锁。这样,就可以确保我现在看到的值,一定不会再被其他人修改了。
2.会话1
3.会话2
4.等会话1commit了
会将结果查询出来。
5.再进行提交
这个时候,会在最新的基础上进行新增。
与刚才的区别:
这个查询的结果,是15,而刚才的查询结果确是10.
因为这里有一段时间再等待,这个行记录被锁定。
四:需要注意的地方
1.是否根据主键决定是否锁表
选中某一个行的时候,如果是通过主键id选中的。那么这个时候是行级锁。 其他的行还是可以直接insert 或者update的。
如果是通过其他的方式选中行,或者选中的条件不明确包含主键。这个时候会锁表。其他的事务对该表的任意一行记录都无法进行插入或者更新操作。只能读取。