我正在构建一个微服务,它使用基于(JTA)的事务管理器。
我的问题是,在分布式数据库场景中,交易管理员是否具有处理并发问题的能力。
场景:
假设一个服务有多个实例正在运行,我们将收到两个请求,将一个帐户中的余额金额更新10。最初,一个帐户可以有$100,第一个实例得到它,并将其增加到$10,但还没有实现。
同时,第二个实例还撤回仍然是100的帐户,并将其增加10美元,然后将其更新到110美元,然后再服务一个更新帐户到110美元。
这时,您一定已经猜到,余额应该增加20美元,而不是10美元。我是否必须编写某种乐观的锁异常机制来防止出现上述情况,还是基于JTA规范的事务管理器已经确保这种情况不会发生?
发布于 2018-08-07 11:13:07
对于这种类型的请求,可以通过乐观并发处理,其中数据库上有一列(时间戳)作为对版本号的引用。
每次进行更改时,它都会修改时间戳值。
如果两个请求同时尝试提交更改,则其中只有一个请求会成功,因为version (时间戳)列将在随后更改时更改其他请求。
发布于 2018-08-07 12:34:27
在分布式数据库场景中,交易管理员有能力处理并发问题吗?
事务和并发是两个独立的概念,虽然在我们也看到并发性的上下文中,事务变得非常重要,但是事务在没有并发性的情况下是非常重要的。
要回答您的问题:不是,事务管理器通常不关心如何处理并发更新中出现的问题。它采用了一种非常天真和简单(通常也是最有意义的)方法:如果在事务启动后,它检测到状态变得不一致(由于并发更新),它只会将其作为异常引发并回滚事务。只要它能够确定事务的ACID属性的所有条件仍然有效,它就会提交事务。
发布于 2018-09-18 03:02:07
事务管理器(作为JTA规范的实现)使多个资源之上的工作变得透明。它确保所有的操作都作为一个单一的工作单元进行。“多资源之上的工作”意味着应用程序可以将数据插入数据库,同时向JMS代理发送消息。事务管理器保证为这两个操作保留ACID属性。以简化的形式,当事务成功完成时,应用程序开发人员可以确保处理了这两个操作。当发生一些问题时,事务管理器需要处理它--可能会抛出一个异常并回滚数据更改。因此,两个操作都没有被处理。这对不需要首先更新数据库、然后更新JMS的应用程序开发人员来说是透明的,并检查所有数据更改是否真的被处理或发生故障。
一般来说,JTA规范的编写没有考虑到微服务体系结构。现在,这取决于您的系统设计(!)但是,如果我认为您有两个微服务,每个服务都附加了自己的事务管理器,那么事务管理器就无法帮助您解决并发问题。事务管理器在某些同步中不工作(通常)。您不使用来自一个微服务的多个资源(事务管理器的用途是什么),而是使用来自多个微服务的一个资源。
因为有一个资源,所以它是所有更新的同步点。这取决于它如何管理并发。考虑到它是一个SQL数据库,那么它取决于它使用的隔离级别(ACID -i= science) )。您的特殊示例谈到丢失的更新现象(https://vladmihalcea.com/a-beginners-guide-to-database-locking-and-the-lost-update-phenomena/)。因为两个微服务都试图更新一条记录。避免此问题的一种解决方案是使用乐观/独立锁(如上面所述的时间戳),另一种解决方案是在数据库中使用可序列化的隔离级别,或者您可以设计应用程序,使其不根据首次读取的内容读取和更新数据,但更改具有update原子的sql查询(或者可能还有其他策略来使用您的数据模型来实现所需的结果)。
总之,这取决于您的事务管理器是如何实现的,它可以在某种程度上帮助您,但这不是它的目的。您的目标应该是检查如何在共享存储中设置隔离级别,并考虑您的应用程序是否需要处理应用程序级别上的丢失更新现象,还是需要您的存储库来管理它。
https://stackoverflow.com/questions/51733502
复制相似问题