事务的ACID属性的责任在哪里?

3
我正在学习有关事务的ACID属性,并在不同的网站上看到了以下陈述。
ACID 是事务所保证的四个属性的首字母缩写:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
我的问题是“guaranteed by transactions”这个短语。
根据我的经验,这些属性并不会自动得到满足。但是作为Java开发人员,我们需要确保这些属性的准则得到满足。
让我们来分别了解每个属性:
1. 原子性:假设当我们创建客户时,账户也应该被创建,因为这是必须的。那么在事务期间,如果在创建账户时出现了异常,开发人员可以采取两种方式:要么回滚整个事务(在这种情况下满足原子性),要么提交事务,那么客户将被创建,但账户不会被创建(这违反了原子性)。因此责任在于开发人员吗?
2. 一致性:对于一致性也是同样的道理。
3. 隔离性:根据定义,隔离性使事务在没有其他进程或事务干扰的情况下执行。但是只有在我们将隔离级别设置为 Serializable 时,才能实现这一点。否则,在另一种情况下,例如读取提交或读取未提交,更改内容对其他事务可见。因此,开发人员需要确保使用 Serializable 实现真正的隔离性吗?
4. 持久性:如果我们提交了事务,即使应用程序崩溃,在应用程序重新启动时也应该提交。不确定这是否需要由开发人员或数据库供应商/事务处理?
因此,根据我的理解,这些ACID属性并不是自动保证的;相反,我们作为开发人员需要实现它们。请让我知道对于每个点的上述理解是否正确?如果您可以为每个点回复一下(是/否也可以),我们将不胜感激。
根据我的理解,在大多数应用程序中,读取提交应该是最合适的隔离级别,尽管这也取决于要求。

几乎所有的答案都假设事务仅由数据库实现,这是不正确的。事务是一个通用概念,可以被许多不同的软件基础架构组件实现:中间层应用服务器、事务监视器、消息系统、对象请求代理等等。 - steve
隔离级别非常依赖于数据库。例如,Oracle不提供未提交读取的隔离级别。无论如何,对于Oracle来说,已提交读取是默认的隔离级别。 - steve
这个问题值得更多的赞同。 - vigamage
2个回答

3

事务保证了ACID的特性:

1) 原子性。事务保证所有更改都被执行或全部不执行。但是您需要手动设置事务的开始和结束,并手动执行提交或回滚操作。根据您使用的技术(EJB…),事务可以由容器管理,将开始和结束设置为您创建的整个“方法”。您可以通过配置控制调用的方法是否需要新事务或现有事务,或者不需要任何事务。

2) 一致性。由原子性保证。

3) 隔离性。您必须定义应用程序所需的隔离级别。默认值取决于数据库、容器等。最常见的是读已提交。请注意锁定,因为它们可能会导致死锁,具体取决于您的逻辑和隔离级别。

4) 持久性。完全由数据库管理。如果提交操作未出错,则几乎所有数据库都保证更改的持久性,但某些情况可能无法保证(写入磁盘的内容被缓存在内存中并稍后刷新...)

总的来说,您应该了解事务并在容器中进行配置,或通过代码声明开始和结束(提交、回滚)。


3
  1. 数据库事务是原子性的:它们要么完全发生,要么根本不发生。仅此而言,并不能说明业务事务是否具有原子性。有各种策略可将业务事务映射到数据库事务上。在最简单的情况下,一个业务事务由一个数据库事务实现(其中通过回滚数据库事务终止业务事务)。然后,数据库事务的原子性意味着业务事务的原子性。然而,一旦业务事务跨越多个数据库事务,情况就变得棘手了…
  2. 见上文。
  3. 你的陈述是正确的。通常,较弱的保证已足以证明正确性。
  4. 数据库事务是持久的(除非硬件出现故障):如果事务已提交,则其效果将持续到其他事务更改数据。但是,如果数据库或数据库和调用代码之间的网络发生故障,则调用代码可能无法知道事务是否已提交。因此,

    如果我们提交事务,即使应用程序崩溃,在应用程序重新启动时也应该已提交。

    是错误的。如果事务已经提交,就没有剩余的事情要做了。

总之,数据库确实提供了强大的保证-关于数据库行为的保证。显然,它不能对整个应用程序的行为提供保证。


业务交易和数据库交易之间的区别是关键。 - APC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接