美文网首页
mysql事务

mysql事务

作者: 呆呆猿 | 来源:发表于2018-12-22 17:55 被阅读0次

隔离级别:可重复读

事务1:

select * from user where id >2;

如果查询结果:  1条数据

此时其它事务 insert into user ('username','password') values ('zhangsan','zhangsan');

再在事务1 中查询 查询结果 1条数据

如果使用 select * from user where id >2 for update;(lock in share mode)

则可以查询2条数据


使用lock in share mode 容易出现死锁;

并且一个事务使用乐观锁锁住行或表 其它事务无法操作行或表;当2个事务都锁住同一块区域后2个事务都无法操作次区域;那这个共享锁 和排他锁的区别呢? 

1. select *** for update 的使用场景

为了让自己查到的数据确保是最新数据,并且查到后的数据只允许自己来修改的时候,需要用到 for update 子句。

2. select *** lock in share mode 使用场景

为了确保自己查到的数据没有被其他的事务正在修改,也就是说确保查到的数据是最新的数据,并且不允许其他人来修改数据。但是自己不一定能够修改数据,因为有可能其他的事务也对这些数据 使用了 in share mode 的方式上了 S 锁。

性能影响:

select for update 语句,相当于一个 update 语句。在业务繁忙的情况下,如果事务没有及时的commit或者rollback 可能会造成其他事务长时间的等待,从而影响数据库的并发使用效率。

select lock in share mode 语句是一个给查找的数据上一个共享锁(S 锁)的功能,它允许其他的事务也对该数据上 S锁,但是不能够允许对该数据进行修改。如果不及时的commit 或者rollback 也可能会造成大量的事务等待。

for update 和 lock in share mode 的区别:前一个上的是排他锁(X 锁),一旦一个事务获取了这个锁,其他的事务是没法在这些数据上执行 for update ;后一个是共享锁,多个事务可以同时的对相同数据执行 lock in share mode。


开启事务后,会在第一次执行查询语句时保一次数据库快照,然后每次查询都是在这个快照里查询数据。

比如:

事务1:执行查询语句

事务2: 执行新增或修改;

事务1:执行查询语句,不会查询出来事务2提交的数据,即便事务2已经提交;


开启事务1,执行查询语句

事务2执行修改操作并提交;

事务1 查询数据,可以查询事务2提交的数据,因为此时事务已才生成快照。


悲观锁、乐观锁、排他锁、共享锁

1、悲观锁:只要加锁就是悲观锁: 如新增、修改, 查询带lock in share mode或 for update;如java里面的lock、synchronize

2、乐观锁:  没有其它人会改值,所以跟没锁一样,但是在数据一致性上需要做要求,比如可以加个版本号,如修改数据时先

查询select name,version from user where id = 1;

更新时使用 update name = "a" where id = 1 and version  = "查询出来的sersion";

此时如果修改数据行数不同证明有几行数据被修改了,可以再进行回滚。如果是使用id精确查询那么update返回结果是0 则表示修改失败。

3、排他锁: 新增、修改 查询带for update

4、共享锁: lock in share mode;

事务1 加了共享锁、事务2 也可以加共享锁

事务1加了共享锁,事务2 无法加排它锁(for update、修改)

事务1 加了共享锁(行锁),事务2可以加共享锁(同一行),然后可以对该行进行修改(即可以再加排它锁);

事务1 加了共享锁(表锁),事务2无法加排它锁,即便先加共享锁也不能再加排它锁。


加锁只会对影响的行加锁,即where条件查询出来的数据(有索引,没有索引会加表锁);

新增也会加锁,属于表锁;如果此事务没有commit;其它事务无法加表锁;

相关文章

网友评论

      本文标题:mysql事务

      本文链接:https://www.haomeiwen.com/subject/bnfwkqtx.html