重点
Repeatable-Read的间隙锁的理解:
userinfo表:(id为主键)
id | username | pwd |
---|---|---|
1 | zhangsan | 333333 |
4 | lisi | 444444 |
10 | cxk | kkkkkk |
查询语句:
事务A:
begin;
update userinfo set pwd="666666" where id>=4;
事务B:
begin;
insert into userinfo (id,username,pwd) values(2,"zhoujielun","zzzzzz");
事务C:
begin;
insert into userinfo (id,username,pwd) values(12,"alan","aaaaaa");
事务D:
begin;
update userinfo set pwd="666666" where id=4;
分析:
4,10行加行锁
[4,10],(10,+无穷)加间隙锁
事务B成功执行,id处于[1,4]之间,无间隙锁,能执行成功。
事务C失败,id处于(10,+无穷),有间隙锁,所以失败。
事务D失败,4和10有行锁,不能被其他事务修改,所以失败。
如果id只是普通字段,是非索引,这条sql语句
update userinfo set pwd="666666" where id>=4;
会锁表,行锁和间隙锁都加,其他事务插入和更新都不能成功。
Read-Committed没有间隙锁,行锁依然有
Spring事务
注解
@EnableTransactionManagement
用于配置类,自动开启事务管理
@Transactional(propagation = Propagation.REQUIRES_NEW)
用于类:将类的所有方法都变成事务方法
用于方法:此方法为事务方法
/**
* 1.添加事务注解
* 使用propagation 指定事务的传播行为,即当前的事务方法被另外一个事务方法调用时如何使用事务。
* 默认取值为REQUIRED,即使用调用方法的事务
* REQUIRES_NEW:使用自己的事务,调用的事务方法的事务被挂起。
*
* 2.使用isolation 指定事务的隔离级别,最常用的取值为READ_COMMITTED
* 3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚,也可以通过对应的属性进行设置。通常情况下,默认值即可。
* 4.使用readOnly 指定事务是否为只读。 表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务。
* 若真的是一个只读取数据库值得方法,应设置readOnly=true
* 5.使用timeOut 指定强制回滚之前事务可以占用的时间。
*/
// @Transactional(propagation= Propagation.REQUIRES_NEW,
// isolation= Isolation.READ_COMMITTED,
// noRollbackFor={UserAccountException.class},
// readOnly=false, timeout=3)
// @Transactional(propagation= Propagation.REQUIRES_NEW)
// @Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 3)
propagation 指定事务的传播行为
https://blog.csdn.net/qq_38526573/article/details/87898161
直达链接