我有一个非常简单的场景,涉及应用程序服务器(Glassfish)中的数据库和JMS.场景很简单:
1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated.
Run Code Online (Sandbox Code Playgroud)
问题是有时在数据库中提交插入之前传递消息.如果我们考虑2阶段提交协议,这实际上是可以理解的:
1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database
Run Code Online (Sandbox Code Playgroud)
我和其他人讨论过这个问题,但答案总是如此:"奇怪,它应该开箱即用".
我的问题是:
以下是关于我对问题的理解的更多细节:
只有在按此顺序处理参与者时才存在此计时问题.如果2PC以相反的顺序(数据库优先,然后是消息代理)处理参与者应该没问题.这个问题是随机发生的,但完全可以重现.
我发现无法在Glassfish文档中控制JTA,JCA和JPA规范中分布式事务中参与者的顺序.我们可以假设它们将在使用它们时按照顺序登记在分布式事务中,但是使用诸如JPA之类的ORM,很难知道何时刷新数据以及何时真正使用数据库连接.任何的想法?
我试图了解三阶段提交如何避免阻塞
请考虑以下两种故障情况:
场景1:在阶段2中,协调器向所有群组发送预提交消息,并且从群组A以外的所有群组获得确认.网络问题阻止群组A接收协调器的预提交消息.群组A超时等待预提交消息并选择中止.然后协调员和队列A都崩溃了.
场景2:协议到达阶段3.协调器向队列A发送doCommit消息.但在它发送更多的doCommit消息之前,协调器崩溃.群组A提交其部分事务然后崩溃.
据我所知,剩下的同类群体在场景1和场景2结束时具有完全相同的状态.因此,当恢复协调员介入时,如何从剩余队列中找出我们是否在场景1中并且中止或我们在方案2和提交,从而避免阻止?
我正在实施涉及分布式资源的两阶段提交.如何模拟参与数据库的失败?拔出网络电缆不起作用,因为它会导致表死锁.我目前在我的应用程序代码中使用钩子,它StaleConnectionException在查询执行之后抛出不同的点,就像查询执行之前一样.我对这种方法的关注是:
我还想在中间点测试,例如在查询执行期间,提交期间(发送准备之后等).现在我将应用程序置于调试模式并进入函数调用并在其间插入插件.但这种方法是手动的,不适用于规模测试.
是否有模拟器/模拟器或工具可以帮助我这样做?
我要描述的内容实际上是两个不同系统之间的两阶段提交问题,我正在寻找有关如何处理它的建议.在我们的Web应用程序中,我们将一些昂贵的/第三方操作(例如发送电子邮件)卸载到带外后台工作进程(我们称之为我们的作业基础结构).
例如,要发送电子邮件,我们会在数据库中创建电子邮件对象和电子邮件作业.然后,我们必须等待我们的工作监视器获取电子邮件作业并发送它.作业监视器基本上通过在空闲时每隔几秒轮询一次数据库来工作.
但是,这会增加电子邮件发送的延迟,并通过轮询添加我在数据库中视为过度负载的内容.如果我们能够在创建电子邮件后立即将电子邮件作业放入队列,那将会更好.
然而,这目前失败有两个原因.首先,队列通常比Web请求快得多.在Web请求提交其数据库事务之前,将拾取电子邮件以进行处理,因此无法正确生成电子邮件.其次,如果Web请求失败,它将回滚其数据库事务,这意味着不应该发送电子邮件.但是,如果它已经被放入队列,则它不再在请求的控制之下.
在队列和数据库之间创建两阶段提交是否有良好的策略?作为参考,我们使用RabbitMQ和MySQL与InnoDB表.我提出的一个想法是在提交数据库事务后将电子邮件作业粘贴到队列中,但这样就可能使电子邮件永远不会排队.我仍然需要创建一个轮询流程来监视应该已发送但未发送的电子邮件.
假设分布式事务中涉及的所有数据库都使用两阶段提交信号实现,它们已准备好提交并具有必要的锁定.协调器发出提交信号,所有数据库都执行它们的部分事务,但是一个SQL数据库由于编程监督而未能考虑这种可能性而遇到零除错误.由于协调员已经发信号通知每个人因为除零而发生的事情是什么?
database transactions 2phase-commit distributed-transactions
我读了一篇文章说:
我们无法在分布式环境中实现传统的交易系统,如微服务中的两阶段提交。
我完全同意这一点。
但是,如果有人可以解释此问题的确切原因,那就太好了。如果我要通过微服务实现两阶段提交,将会遇到什么问题?
提前致谢
java 2phase-commit distributed-system distributed-transactions microservices
我正在考虑一种设置,在该设置中,实体存储在文档数据库(例如CouchDB)和图形数据库(例如Neo4j)中。基本原理是将每个实体信息(数据,blob,值,复杂的内部结构)存储在文档db中,而将实体关系(父,子,关联实体)存储在图db中。
有没有人做过/看到过/被这样的装置咬过?我应该期待什么样的问题?首先想到的是两阶段提交。但是备份在这里也有问题。
couchdb 2phase-commit neo4j graph-databases document-database
我读了很多文章并感到困惑。
\n\n意见 1:\n2PC 非常高效,交换的消息数量最少且延迟较低。\n来源:\n http://highscalability.com/paper-consensus-protocols-two-phase-commit
\n\n意见2:\n分布式事务很难扩展到高水平,而且会降低吞吐量。由于2PC保证ACID,由于其复杂的协调算法,带来了很大的负担。\n来源:http ://ivoroshilin.com/2014/03/18/distributed-transactions-and-scalability-issues-in-large-scale-distributed -系统/
\n\n意见3:\n\xe2\x80\x9c一些作者声称两阶段提交的支持成本太高,因为\n它带来了性能或可用性问题。我们认为,最好让应用程序程序员处理由于过度使用事务而出现的性能问题,而不是总是围绕事务的缺乏进行编码。在 Paxos 上运行\n两阶段提交可以缓解可用性问题。\xe2\x80\x9d\n来源:http ://courses.cs.washington.edu/courses/csep552/13sp/lectures/6/spanner.pdf
\n\n意见 4:\n2PC 协调器还代表单点故障,这对于关键系统来说是不可接受的 - 我相信它是协调器。\n来源:http://www.addsimplicity.com/adding_simplicity_an_engi/2006/12/2pc_or_not_2pc_。 html
\n\n前3种意见相互矛盾。第4条我认为是正确的。请澄清什么是错误的,什么是正确的。如果能够给出事实,那就太好了。
\ndatabase scalability 2phase-commit distributed-transactions consensus
我目前正在研究二阶段和三阶段提交。
3PC协议试图通过添加一个额外的阶段preCommit来消除2PC协议\xe2\x80\x99s的系统阻塞问题。正如这里提到的
根据这篇文章,如果协调器在任何时候崩溃,恢复节点可以接管事务并从任何剩余副本查询状态。例如,如果任何剩余副本回复恢复节点它处于预提交状态,则恢复节点将知道失败的协调器已发送预提交消息,并且所有副本已同意提交。
我的问题是,为什么两阶段提交不能做同样的事情?当协调器发生故障时,恢复节点会查询那些剩余的节点并查看其中是否有任何节点已经处于提交阶段?
我已阅读服务器帖子,但仍然不知道三阶段提交试图解决的确切问题是什么以及如何解决?
\n请帮忙!
\n2phase-commit ×10
database ×5
transactions ×4
java ×2
commit ×1
consensus ×1
couchdb ×1
cqrs ×1
java-ee ×1
jms ×1
neo4j ×1
queue ×1
scalability ×1
websphere ×1