赞
踩
数据库事务是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。
对于一些业务网站而言,产品库的扣减、交易记录以及账户都必须是要么同时成功,要么同时失败。又例如在一些特殊场景下,如一个批处理,它将处理多个交易,但是在一些交易中发生了异常,这个时候就不能将所有的交易都回滚(否则,那些本能够正常处理的业务也无端地被回滚了)。
通过@Transactional注解的相关配置,Spring就会知道在哪里启动事务机制,其约定流程如下图所示:
package org.springframework.transaction.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Transactional { // 通过bean name指定事务管理器 @AliasFor("transactionManager") String value() default ""; // 同value属性 @AliasFor("value") String transactionManager() default ""; // 指定传播行为 Propagation propagation() default Propagation.REQUIRED; // 指定隔离级别 Isolation isolation() default Isolation.DEFAULT; // 指定超时时间(单位:秒) int timeout() default -1; // 是否只读事务 boolean readOnly() default false; // 方法在发生指定异常时回滚,默认是所有异常都回滚 Class<? extends Throwable>[] rollbackFor() default {}; // 方法在发生指定异常名称时回滚,默认是所有异常都回滚 String[] rollbackForClassName() default {}; // 方法在发生指定异常时不回滚,默认是所有异常都回滚 Class<? extends Throwable>[] noRollbackFor() default {}; // 方法在发生指定异常名称时不回滚,默认是所有异常都回滚 String[] noRollbackForClassName() default {}; }
@Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao = null; @Override @Transactional(isolation= Isolation.READ_COMMITTED, timeout = 1) public int insertUser(User user) { return userDao.insertUser(user); } @Override @Transactional(isolation= Isolation.READ_COMMITTED, timeout = 1) public User getUser(Long id) { return userDao.getUser(id); } }
mysql事务详解:(隔离级别 -> 读分类 -> 锁)
未提交读:允许脏读,也就是可能读取到其他会话中未提交事务修改的数据;
脏读:当一个会话的事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个会话的事务也访问这个数据,然后使用了这个数据;
…
提交读解决了脏读的现象:
提交读存在的问题 不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,则第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读;
…
可重复存在的问题 幻读:会话T1事务中执行一次查询,然后会话T2新插入一行记录,这行记录恰好可以满足T1所使用的查询条件。然后T1又使用相同的查询再次对表进行检索,但是此时却看到了事务T2刚才插入的新行。这个新行就称为"幻象",因为对T1来说这一行就像突然出现的一样
串行读:完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞;
不可重复读和幻读读区别:不可重复读重点在于update和delete,幻读重点在于insert
参考文章:
https://www.jianshu.com/p/cd6bb6adfb38
《深入浅出Spring Boot 2.x》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。