有什么解决方案可以防止这种数据不一致的发生?
Traditionally, distributed transaction managers are used. A few years ago in the Java EE world you might have created these services as EJBs which were deployed to different nodes and your API gateway would have made remote calls to those EJBs. The application server (if configured correctly) automatically ensures, using two phase commit, that the transaction is either committed or rolled back on each node, so that consistency is guaranteed. But that requires that all the services be deployed on the same type of application server (so that they are compatible) and in reality only ever worked with services deployed by a single company.
是否存在允许事务跨越多个REST请求的模式?
对于SOAP(好吧,不是REST),有WS-AT规范,但我曾经集成过的任何服务都不支持该规范。对于REST, JBoss已经准备好了一些东西。否则,“模式”是要么找到一个可以插入到您的体系结构中的产品,要么构建您自己的解决方案(不推荐)。
我已经为Java EE发布了这样一个产品:https://github.com/maxant/genericconnector
根据您引用的论文,还有来自Atomikos的Try-Cancel/Confirm模式和相关Product。
BPEL引擎使用补偿处理远程部署服务之间的一致性。
或者,我知道REST可能不适合这个用例。处理这种情况的正确方法可能是完全放弃REST并使用不同的通信协议,如消息队列系统?
将非事务资源“绑定”到事务中有很多方法:
As you suggest, you could use a transactional message queue, but it will be asynchronous, so if you depend on the response it becomes messy.
You could write the fact that you need to call the back end services into your database, and then call the back end services using a batch. Again, async, so can get messy.
You could use a business process engine as your API gateway to orchestrate the back end microservices.
You could use remote EJB, as mentioned at the start, since that supports distributed transactions out of the box.
或者我应该在我的应用程序代码中强制一致性(例如,通过有一个后台作业来检测不一致并修复它们,或者通过在我的用户模型上有一个“state”属性与“creating”,“created”值等)?
玩魔鬼的拥护者:为什么要建立这样的东西,当有产品为你做这件事(见上文),可能比你做得更好,因为他们是经过试验和测试的?