• 19.声明式事务的事务隔离级别和事务传播行为


    一:事务属性:事务隔离级别

    ①介绍

    数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事 务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同 的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

    隔离级别一共有四种:

    • 读未提交:READ UNCOMMITTED

    允许Transaction01读取Transaction02未提交的修改。

    • 读已提交:READ COMMITTED、

    要求Transaction01只能读取Transaction02已提交的修改。

    • 可重复读:REPEATABLE READ

    确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它 事务对这个字段进行更新。

    • 串行化:SERIALIZABLE

    确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它 事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

    ②:使用方式

    1. @Service
    2. public class BookServiceImpl implements BookService {
    3. @Autowired
    4. private BookDao bookDao;
    5. @Override
    6. @Transactional(
    7. isolation = Isolation.DEFAULT
    8. )
    9. public void buyBook(Integer userId, Integer bookId) {
    10. // try {
    11. // TimeUnit.SECONDS.sleep(5);
    12. // } catch (InterruptedException e) {
    13. // e.printStackTrace();
    14. // }
    15. //查询图书的价格
    16. Integer price = bookDao.getPriceByBookId(bookId);
    17. //更新图书的库存
    18. bookDao.updateStock(bookId);
    19. //更新用户的余额
    20. bookDao.updateBalance(userId,price);
    21. System.out.println(1/0);
    22. }
    23. }

    二:事务属性:事务传播行为 

    ①介绍

    当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中 运行,也可能开启一个新事务,并在自己的事务中运行。

    ②测试

    1. public interface CheckoutService {
    2. }
    1. @Service
    2. public class CheckoutServiceImpl implements CheckoutService {
    3. }

    在BookController中添加方法,然后到Service创建这个方法

    1. @Autowired
    2. private CheckoutService checkoutService;
    3. public void checkout(Integer userId,Integer[] bookIds) {
    4. checkoutService.chekout(userId,bookIds);
    5. }

    CheckoutService接口添加方法

    1. void checkout(Integer userId, Integer[] bookIds);
    2. }

     CheckoutServiceImpl实现类添加方法

    1. @Override
    2. public void checkout(Integer userId, Integer[] bookIds) {
    3. }

    然后我们添加一个结账操作

    1. public void checkout(Integer userId,Integer[] bookIds) {
    2. checkoutService.checkout(userId,bookIds);
    3. }
    1. @Service
    2. public class BookServiceImpl implements BookService {
    3. @Autowired
    4. private BookDao bookDao;
    5. @Override
    6. @Transactional(
    7. isolation = Isolation.DEFAULT
    8. )
    9. public void buyBook(Integer userId, Integer bookId) {
    10. // try {
    11. // TimeUnit.SECONDS.sleep(5);
    12. // } catch (InterruptedException e) {
    13. // e.printStackTrace();
    14. // }
    15. //查询图书的价格
    16. Integer price = bookDao.getPriceByBookId(bookId);
    17. //更新图书的库存
    18. bookDao.updateStock(bookId);
    19. //更新用户的余额
    20. bookDao.updateBalance(userId,price);
    21. // System.out.println(1/0);
    22. }
    23. }
    1. @Service
    2. public class CheckoutServiceImpl implements CheckoutService {
    3. @Autowired
    4. private BookService bookService;
    5. @Override
    6. @Transactional
    7. public void checkout(Integer userId, Integer[] bookIds) {
    8. for (Integer bookId : bookIds) {
    9. bookService.buyBook(userId,bookId);
    10. }
    11. }
    12. }

    此时会发现我们两个方法都添加了@Transactional注解,但它会默认的使用我们的结账方法添加的注解

    我们可以通过propagation中的Propagations属性设置事务传播行为

    例:

    @Transactional(propagation = Propagation.REQUIRED)使用的是我们调用者的事务

    @Transactional(propagation = Propagation.REQUIRES_NEW)使用的是我们被调用的方法本身的事务

    如: 

    1. @Service
    2. public class BookServiceImpl implements BookService {
    3. @Autowired
    4. private BookDao bookDao;
    5. @Override
    6. @Transactional(
    7. // isolation = Isolation.DEFAULT
    8. propagation = Propagation.REQUIRES_NEW
    9. )
    10. public void buyBook(Integer userId, Integer bookId) {
    11. // try {
    12. // TimeUnit.SECONDS.sleep(5);
    13. // } catch (InterruptedException e) {
    14. // e.printStackTrace();
    15. // }
    16. //查询图书的价格
    17. Integer price = bookDao.getPriceByBookId(bookId);
    18. //更新图书的库存
    19. bookDao.updateStock(bookId);
    20. //更新用户的余额
    21. bookDao.updateBalance(userId,price);
    22. // System.out.println(1/0);
    23. }
    24. }
  • 相关阅读:
    Webpack完整打包流程分析
    HDU - 1114 Piggy-Bank(完全背包)
    阿里云云原生一体化数仓 - 数据安全能力解读
    eclipse配置tomcat详解(图文版)
    最高频的五个面试题
    数据结构————深度寻路算法
    C++ string类常用函数
    基于ASP.NET MVC + Bootstrap的仓库管理系统
    标签名选择器、id选择器、class类型选择器、组合选择器
    8 mysql中的索引2
  • 原文地址:https://blog.csdn.net/m0_56379670/article/details/127560210