事务细节
一、@Transactional()
1、@Transactional()中
-
isolation-Isolation:事务隔离级别
-
propagation = Propagation:事务的传播行为
-
noRollbackFor-Class[]:哪些异常事务可以不回读
noRollbackForClassName-String[] -
rollbackFor-Class:哪些异常事务需要回滚
rollbackForClassName-String[] -
readOnly-boolean:设置事务为只读
-
可以进行事务优化:
-
readOnlu-true:加快查询速度,不用管事务那一堆操作
-
timeout-int:(秒)超时,事务超出指定时长后自动终止并回滚
2、异常分类:
- 运行时异常:(非检查异常)可以不用处理,默认都回滚
- 编译时异常:(检查异常),要么try-catch,要么在方法上声明throws,默认不回滚
3、事务的回滚:默认发生异常都回滚,发生编译异常不会回滚
- noRollbackFo:哪些异常事务可以不回滚;(可以让原来默认回滚的异常给他不回滚)
- rollbackFor:原本不回滚(原本编译时异常是不回滚的)的异常让其回滚;
@Service
public class BookService {
@Autowired
BookDao bookDao;
@Transactional(timeout = 3,readOnly = false,noRollbackFor={ArithmeticException.class,NullPointerException.class})
public void checkout(String username,String isbn){
// 减库存
bookDao.updateStock(isbn);
int price = bookDao.getPrice(isbn);
//减余额
bookDao.updataBalance(username,price);
int i=10/0;
}
}
二、数据库事务并发问题:
- 脏读
- 不可重复读
- 幻读
三、隔离级别:
数据库系统必须具有隔离并发运行各个事务的能力,使他们不会互相影响,避免各种并发问题,一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但是并发性越弱。
- 读未提交Read uncommitted:就是一个事务可以读取另一个未提交事务的数据,是级别最低的隔离机制
- 缺点:会产生脏读、不可重复读、幻读
- 读已提交Read committed:就是一个事务要等另一个事务提交后才能读取数据,oracel默认隔离级别
- 缺点:会产生不可重复读、幻读
- 可重复读Repeatable read:开始读取数据(事务开启)时,不再允许修改操作,是MySQL的默认隔离级别
- 缺点:会产生幻读
- 串行化Serializable:数据库进入单线程,可以避免任何并发问题,但是性能十分低下,隔离级别最高
- 缺点:可以解决并发事务的所有问题。但是效率低下,消耗数据库性能,一般不适用
1、读未提交:发生脏读
2、读已提交:避免脏读,没有避免不可重复读
3、可重复读(快照读):只要在同一个事务期间,第一次是什么以后就是什么,即使外界的数据都不存在了