首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@Transactional(isolation = Isolation.SERIALIZABLE,propagation = Propagation.REQUIRES_NEW)未按预期工作

@Transactional(isolation = Isolation.SERIALIZABLE,propagation = Propagation.REQUIRES_NEW)未按预期工作
EN

Stack Overflow用户
提问于 2020-03-11 14:08:28
回答 1查看 568关注 0票数 1

我有一个用例,如下所述,我试图在SERIALIZABLE或REPEATALBE读隔离中使用transaction来完成它。

这是一个书店系统。最简单,没有用户管理和价格扣除限制。书店的数量与它一起。对于每个订单请求,我需要检查可用副本的数量,如果> 0,则减去1。

为此,我尝试使用transaction,其中i 1.读取book对象并获取count 2。如果count >0,则更新db中的count ( count -1 )。

必须在单个事务中完成这两项操作,以确认原子性/一致性。

我已经在我的spring启动服务中编写了这个方法:

代码语言:javascript
复制
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Book updateBookQuantity(String isbn) {
        Book book = null;

        Optional<Book> bookRecord = bookRepository.findById(isbn);
        try {
            System.out.println("threadname on hold= " + Thread.currentThread().getId());
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("threadname resumed = " + Thread.currentThread().getId());

        if (bookRecord.isPresent()) {
            book = bookRecord.get();
            System.out.println("book count == " + Thread.currentThread().getId() + "  "+ book.getQuantity());

            if (book.getQuantity() > 0) {
                book = bookRecord.get();
                book.setQuantity(bookRecord.get().getQuantity() - 1);
                bookRepository.save(book);
            } else {
                throw new BookOutOfStockException(book.getTitle());
            }
        }
        return book;
    }

现在,当我尝试使用Rest api运行它(同时命中2次)时,我哪里出错了?这两个线程并行运行,都将计数读为1并将其更新为0。理想情况下,一个应该已经通过,另一个应该抛出BookOutOfStockException异常。我没有配置任何特定于事务管理器的东西,它只由spring boot处理。

这段代码哪里出了问题?配置是导致这种情况的原因吗?注意:使用spring-data-jpa,数据库: mysql

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-17 01:29:24

使用InnoDB引擎解决了此问题。要更改引擎,请使用正确的方言。spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

MyIASM不支持事务。这就是为什么在上面的问题中没有创建事务的原因。Innodb支持事务和外键。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60630151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档