并发问题中的悲观锁和乐观锁
1.悲观锁:很悲观,每次去拿数据的时候都认为别人会修改,所以每次去拿数据都会“上锁”,操作完成后再“解锁”。在数据加锁期间,其他人如果来拿数据就会等待,直到去掉锁。好比抢厕所。数据库中的悲观锁有“锁表”,“锁行”等。c#程序中有lock(obj){...}
2.乐观锁:很乐观,认为一般情况不会被占用,自己先占了在说,占完后再看看是不是占上了,如果没有占上就是失败了。
两种锁各有优缺点。悲观锁体验更好,但是对系统性能影响大,只适合并发量不大的场合。乐观锁适用于“写少读多”的情况,加大了系统吞吐量,但是“乐观锁可能失败”给用户的体验不好。
悲观锁的使用
https://www.cnblogs.com/bdqczhl/p/13785567.html
一定要在同一个事务中,在查询语句的表名后加上 with(xlock,ROWLOCK) 。 xlock表示“排他锁”,加上排他锁后其他人再获得这个锁的话就要等待开锁(事务结束)。 ROWLOCK为行锁,锁定查询出来的行。
乐观锁的使用
sqlserver数据库中有个特殊的字段类型 rowversion ,列名叫什么无所谓,这个字段的值不需要程序员维护,每次修改这行数据的时候,对应的 rowversion 都会自动变化。其他厂商的数据库中这个字段的数据类型是时间戳(TimeStamp)类型。
乐观锁“抢女友”的思路很简单:抢之前查下rowversion,查出来的值是123。那更新语句就是:update T_Girls set BF = 'me' where id = 1 and rowversion = 123
更新语句多加了这个rowversion条件,执行后如果受影响的行数是0,说明rowversion变化了,刚才有人抢先了,抢女友失败。
数据库中rowversion类型对应 c#中数据类型是byte[]