XA 事务中的数据一致性
假设我们有一个数据库(例如Oracle)和一个JMS提供商(例如HornetQ)参与XA事务。一条消息被发送到 JMS 队列,并且一些数据将在同一分布式事务中持久保存在数据库中。提交事务后,消息使用者将读取持久化的数据,并在单独的事务中处理它们。
关于第一个XA事务,事务管理器可以执行以下事件序列(例如JBoss)
- 准备(大黄蜂Q)
- 准备(甲骨文)
- commit (HornetQ)
- commit (Oracle)
如果消息使用者在 HornetQ 中完成提交后开始读取数据,但仍在 Oracle 中执行,会发生什么情况?消息使用者是否会读取过时的数据?
这个问题可以推广到参与XA事务的任何类型的多个资源,即是否有可能在一个小的时间窗口(当执行提交阶段时)中,来自另一个并发事务的读取器可以获得不一致的状态(通过从一个资源读取提交的数据并从另一个资源读取过时的数据)?
我想说的是,事务资源防止这种情况的唯一方法是在准备阶段完成后阻止受影响数据的所有读取器,直到发出提交。这样,上面提到的示例消息使用者将阻塞,直到数据提交到数据库中。