四种隔离级别
- 读未提交
- 读已提交
- 可重复读
- 序列化
如果没有隔离,多线程出现的问题
- 脏读
- 第一类丢失更新
- 不可重复读
- 第二类丢失更新
- 幻读
解释
脏读:一个连接读到另一个连接修改但没有提交的数据
第一类丢失更新:a连接开启事务,b连接随后开启事务并更新完,但a发生异常回滚,回到a最初的状态,把b的更新给淹没
不可重复读:a读数据假设为1,b修改数据改为2并提交,a再读数据发现数据变为2
第二类丢失更新:a连接开启事务,b连接随后开启事务并更新完,a提交事务,把b的更新给淹没
幻读:a查询表中共多少条数据,之后b插入一条数据,a再读就会发现前后两次不一致。
选择隔离级别避免发生问题
在spring中添加事务
声明式事务
- 注解
- xml配置文件
编程式事务
TransactionTemplate 这种适合更细粒度的事务
代码实战
isolation 隔离级别
propagation 事务传播
常用的三种:
- required
- required-new
- nested
解释
required:a调用b,如果a有事务,就按a的事务来,没有就创建事务,b失败回滚
required-new:a调用b,创建一个新事务,并暂停外部事务,就是说不管a是够成功,b都完成了
nested:如果存在外部事务a,则嵌套到外部事务中,a并有独立的提交和回滚,b如果失败则回滚,但a不一定,也就是说a不管b成功与否,自己先完成再说,否则就和required-new一样
如果事务中发生情况就不会插入成功
声明式事务
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.REQUIRED)
public void insert(){
User user = new User();
userService.insertUser(user);
int a=1/0;
}
编程式事务
public void insert(){
TransactionTemplate template = new TransactionTemplate();
template.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
template.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
User user = new User();
userService.insertUser(user);
int a=1/0;
return null;
}
});
}