使用Speedment实现事务处理

Posted chszs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Speedment实现事务处理相关的知识,希望对你有一定的参考价值。

使用Speedment实现事务处理

  • 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。

一、Speedment介绍

Speedment是一个开源的、基于Java的、流式ORM工具包和运行时工具,它把对现有数据库和表的各种操作封装成Java 8的Stream操作。Speedment的新版本还提供了支持数据库事务处理的便捷操作方式。

Speedment在GitHub的地址:https://github.com/speedment/speedment

一行代码

搜索时长大于120分钟的电影。

使用SQL查询:

SELECT
    `film_id`, `title`, `description`, `release_year`, `language_id`,
    `original_language_id`, `rental_duration`, `rental_rate`, `length`,
    `replacement_cost`, `rating`, `special_features`, `last_update`
FROM
    `sakila`.`film`
WHERE
    (`length` > 120)

使用Speedment:

Optional<Film> longFilm = films.stream()
    .filter(Film.LENGTH.greaterThan(120))
    .findAny();

可见,使用Speedment无需手动编写SQL语句,而且代码更简洁。

二、Speedment实现事务处理

本文讲述怎样学习使用开源的Speedment ORM工具和Java 8/9实现数据库的事务处理。

有时我们要确保我们的数据库操作是原子执行的,并且与其他数据库操作是相互隔离的。这就是事务处理发挥作用的地方。事务处理是一组操作建议,可以被数据库管理系统视为原子操作。因此,事物处理中的所有操作要么都被接受,要么都不接受。事务处理的另一个优点是事务处理开始时,数据库的状态将在本地“冻结”,所以在事务处理中我们不会看到其他线程的更新。

更新

想象一下,假设我们正在填写一个银行账户操作的申请表,我们想从一个账户(1)转移100美元到另一个账户(2)。在这种情况下,最重要的是我们的钱不能丢失(也即从账户1中扣除了100美元,但却没存入账户2中),或者甚至更糟(即账户2存入了100美元但不是从账户1中扣除的金额,银行会找用户的麻烦)。遇到这种情况,我们可以使用如Speedment这样的数据库事务处理来保证安全:

txHandler.createAndAccept(tx ->
    Account sender = accounts.stream()
        .filter(Account.ID.equal(1))
        .findAny()
        .get();
    Account receiver = accounts.stream()
        .filter(Account.ID.equal(2))
        .findAny()
        .get();
    accounts.update(sender.setBalance(sender.getBalance() - 100));
    accounts.update(receiver.setBalance(receiver.getBalance() + 100));
    tx.commit();

当调用tx.commit()方法时,两个更新将以原子操作的方式提交给数据库,并对其他所有线程可见。如果我们不显式调用tx.commit()方法,那么事务将自动回滚(即更新不会有任何影响,相关操作都被丢弃)。

准备工作

在使用事务处理之前,我们需要获取一个TransactionHandler对象,比如这样:

BankApplication app = ....
TransactionComponent transactionComponent = app.getOrThrow(TransactionComponent.class);
TransactionHandler txHandler = transactionComponent.createTransactionHandler();

然后AccountManager可以从应用程序中检索,比如:

AccountManager accounts = app.getOrThrow(AccountManager.class);

以上是关于使用Speedment实现事务处理的主要内容,如果未能解决你的问题,请参考以下文章

In-Memory:内存优化表的事务处理

Spring事务专题事务的基本概念,Mysql事务处理原理

MySQL事务处理特性的实现原理

Java实现通用线程池

MySQL事务处理特性的实现原理

MySQL事务处理特性的实现原理