悲观锁和乐观锁

Spring事务隔离级别

事务级别                     Dirty(脏读) non-repeatable(不可重复读) phantom(幻读)         
Read Committed     不会       会                         会
Read Uncommitted   会         会                         会

Repeatable Read    不会       不会                        会 

Serializable       不会       不会                       不会

Propagation

事务传播行为

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

Isolation

事务隔离级别

@Transactional(isolation = Isolation.READ_UNCOMMITTED)读取未提交数据(会出现脏读, 不可重复读) 基本不使用

@Transactional(isolation = Isolation.READ_COMMITTED)读取已提交数据(会出现不可重复读和幻读)

@Transactional(isolation = Isolation.REPEATABLE_READ)可重复读(会出现幻读)

@Transactional(isolation = Isolation.SERIALIZABLE)串行化

Repeatable Read是MySQL的预设隔离等级。

Read Committed是SQL Server的预设隔离等级。

Read Committed 和 Repeatable Read 是最常用的两种事务。而 Repeatable Read 比Read Committed 更能保证数据一致性。

特点:

Read Committed会阻塞其它事务中的update,但不会阻塞select。

Repeatable Read不但会阻塞其它事务中的update,还会阻塞select。

Read Committed 和 Repeatable Read 的相同点是:都会阻塞其它事务的update语句。

Read Committed 和 Repeatable Read 的不同点是:Read Committed 不会阻塞其它事务的select语句,但Repeatable Read阻塞。

注意,Read Committed 和 Repeatable Read 都是行级锁,它们只会锁住与自己相关的记录。当事务提交之后,阻塞的语句就会继续执行。

悲观锁:

悲观锁是指假设并发更新冲突会发生,所以不管冲突是否真的发生,都会使用锁机制。

悲观锁会完成以下功能:锁住读取的记录,防止其它事务读取和更新这些记录。其它事务会一直阻塞,直到这个事务结束。

悲观锁是在使用了数据库的事务隔离功能的基础上,独享占用的资源,以此保证读取数据一致性,避免修改丢失。

悲观锁可以使用Repeatable Read事务,它完全满足悲观锁的要求。

乐观锁:

乐观锁不会锁住任何东西,也就是说,它不依赖数据库的事务机制,乐观锁完全是用系统层面的东西。

如果使用乐观锁,那么数据库就必须加版本字段,否则就只能比较所有字段,但因为浮点类型不能比较,所以实际上没有版本字段是不可行的。

相关推荐