我知道与数据库中的对象交互需要以下内容:
db.getTransaction().begin();
//Code to modify objects in the data base
db.getTransaction().commit();
但是当我使用函数find(object.class, object.id)时有必要吗?
最佳答案
Is it necessary to begin a transaction to find an object in the data base?
取决于您所说的“交易”一词的含义。
数据库完成事务中的所有事情。时期。因此,简单来说,"is",有必要开始事务,因为如果不这样做,您就无法与数据库交互。
但是,数据库有一个“方便”的功能,您可以像不存在事务一样工作。这是个谎言;它仅仅意味着您发送到数据库的每条语句都默默地包含在“START TRANSACTION;”中和“提交”;来电。这称为“自动提交”模式(而不是“无事务模式”),因为这是正确的词:它在每个事务后自动提交。
因此,在基本的 JDBC 中(java 中所有基于 SQL 的数据库交互通常构建于其上的基础层,但请注意,您正在使用构建在其之上的某种库!),您可以只运行选择查询,通过使用自动提交模式,“不需要”处理事务。
但是,自动提交模式通常不是一个好主意。
事务是数据库设计的基础。即使您只是进行“读取”查询,事务仍然很重要。它们保证一致性和原子性。这是一个例子:
假设您想知道 Jane 的银行余额和 Jack 的银行余额,例如检查余额是否足以支付房屋租赁或诸如此类的费用。
看起来很简单:
SELECT balance FROM bankaccounts WHERE user = 'Jack';
SELECT balance FROM bankaccounts WHERE user = 'Jane';
然后把它们加起来,对吧?
错误。
如果您在自动提交模式下运行它,那么 Jack 可能有 50k,Jane 有 100k,但总和似乎是 200k。这是通过 jack 设法在两条语句之间将他的 50k 转移给 jane 来完成的,这样你就得到了 50k+150k = 200k 的总和,尽管这是一个谎言。
因此,事务也适用于只读 session ;假设您使用正确的隔离级别(SERIALIZABLE 是合理的级别),它们甚至可能导致重试。通过交易,您每次都会得到 150k 的正确答案,无论简和 jack 何时或多久来回转移资金以试图欺骗您。
JDBC 本身没有“getTransaction()”这个东西,或者“开始”,一般来说,这不是“执行”事务的正确方法。因此,不清楚您在这里使用的是哪个第三方库。
正确的数据库抽象看起来像:
int sum = dbAccess.executeInt(db -> {
// query or modify things here:
return
db.select("SELECT balance FROM bankaccount WHERE user = ?", "Jack").singleInt() +
db.select("SELECT balance FROM bankaccount WHERE user = ?", "Jane").singleInt();
};
它需要在 lambda 中来处理重试,并且它与数据库的所有交互都是事务性的这一事实非常吻合。
您可能想再仔细阅读一下文档;这种(使用 lambda 表达式)策略可能会晚于您的数据库库的开始(lambda 表达式是在 java8 中添加的;诚然,那是十年前的事了)。
关于java - 是否需要开始事务才能在数据库中查找对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67269332/