有时我们希望确保我们的数据库操作以原子方式执行并与其他操作分开。这就是交易发挥作用的地方。事务是一组操作
可能会或可能不会被数据库接受为原子操作的提议。因此,要么接受交易中的所有操作,要么不接受交易的任何操作。事务的另一个优点是,当事务开始时,数据库的状态将在本地“冻结”,因此我们不会在事务中看到其他线程的更新。
Speedment 是一种开源 Stream ORM Java 工具包和运行时 Java 工具,可将现有数据库及其表包装到 Java 8 流中。 Speedment 的更高版本以一种易于使用的方式支持数据库事务。
想象一下,我们正在编写一个带有账户的银行应用程序,我们要将 100 美元从一个账户 (1) 转移到另一个账户 (2)。在这种情况下,重要的是钱不会消失(即从 1 中扣除但从未存入 2)或者更糟的是,钱会被复制(即存入 2 但不从 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 交易的更多信息。
访问 GitHub 并在此处阅读有关 Speedment 开源的所有信息。
标签2: Java教程地址:https://www.cundage.com/article/jcg-transactions-made-simple-using-speedment-3-0-17.html