事务手动提交和XA事务问题及思考

2021-08-31 14:34:23 浏览数 (1)

一、背景

今天@无聊之园提出 一个问题 “手动将多个数据库事务提交和XA效果类似,比如事务A,事务B一起提交,前面报错就一起回滚,否则一起先后执行提交”。除非是提交的时候会有失败的可能,否则没有问题。引发了技术群里进行了一番探讨。

那么事务提交的时候会失败吗?哪些情况下会失败??

XA事务的目的是啥,使用场景是啥?

通过这些对我们的学习和求职又能够带来何种启发?

二、研究

2.1 SOF上一个类似的问题 “Can a COMMIT statement (in SQL) ever fail? How?”

https://stackoverflow.com/questions/3960189/can-a-commit-statement-in-sql-ever-fail-how

OMMIT may fail. You might have had sufficent resources to log all the changes you wished to make, but lack resources to actually implement the changes. And that's not considering other reasons it might fail:

  1. The change itself might not fit the constraints of the database.
  2. Power loss stops things from completing.
  3. The level of requested selection concurrency might disallow an update (cursors updating a modified table, for example).
  4. The commit might time out or be on a connection which times out due to starvation issues.
  5. The network connection between the client and the database may be lost.

And all the other "simple" reasons that aren't on the top of my head.

列举了五几种情况,其中包括不符合数据库的约束,断电,并发更新问题,提交超时,网络中断等。

《org.hibernate.TransactionException: commit failed》更是印证了这个说法。

2.3 事务被kill

之前开发的时候公司运维系统对超过某个执行时间的线程就会kill掉。

假如这个时候第一个事务提交成功后第二个事务还没来得及提交就被kill,显然也会提交失败。

因此手动多个事务一起提交不太靠谱,无法可靠的保证事务的一致性。

三、延伸

3.1 XA事务相关好文

《XA 事务处理》https://www.infoq.cn/article/xa-transactions-handle 对XA事务给出了详细的讲解。

X/Open XA 接口是双向的系统接口,在事务管理器以及一个或多个资源管理器之间形成通信桥梁。

事务管理器控制着 JTA 事务,管理事务生命周期,并协调资源。在 JTA 中,事务管理器抽象为 javax.transaction.TransactionManager 接口,并通过底层事务服务(即 JTS)实现。

资源管理器负责控制和管理实际资源(如数据库或 JMS 队列)。

下图说明了事务管理器、资源管理器,以及典型 JTA 环境中客户端应用之间的关系:

 XA 接口形成了事务管理器和资源管理器之间的通信桥梁。因为 XA 接口的双向特质,XA 支持两阶段提交协议

XA的使用场景:仅在同一个事务上下文中需要协调多种资源(即数据库,以及消息主题或队列)时,才有必要使用 X/Open XA 接口。

另外还涉及到了 两阶段提交等知识,读者感兴趣自己去看。

四、思考

只要不是原子的都可能在中间环节出问题。

比如面试中常问的多线程同步问题,i 细节问题,比如面试中常问的MQ重复消费等问题。

根据墨菲定律,“如果事情有变坏的可能,不管这种可能性有多小,它总会发生”。在计算机领域同样适用!

(通过这一点回头看看我的另外一篇文章《拓宽知识面的重要性》,或许就会突然更加认同一些。人总是拿已有的知识来解决问题,如果你不懂得得这一块知识,就不容易融会贯通帮助你更好的理解和解决问题)

就像是唯一键问题,虽然逻辑上某些数据是唯一的,但是没有唯一键约束,高并发场景下或者其他异常情况很容易导致重复数据。

另外虽然理想状态下,一起提交都应该可以正常提交,但是高并发场景下或者一系列意外情况都可能导致事务提交失败。

生活中也是一样,前一段时间刚结束高考,每年很多老师都一再强调,很多考生极其重视,可是每年都有忘了带身份证的,每年都有迟到的等等。

最后这给我的一个非常大的启发,我们可以利用逆向思维来思考方案可能存在的问题。

比如对方服务如果挂了怎么办?如果数据库被打爆了怎么办?如果网线被挖断了怎么办?

缓存穿透,缓存雪崩,集群脑裂,消息重复消费等等高并发分布式的很多问题无不是某个环节出了问题。

既然面试官老这么问,我们学的时候为啥不这么去思考呢??为何不能成为我们学习的一种思考习惯呢?

创作不易,如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。 另外欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。 https://t.zsxq.com/Z3bAiea  申请时标注来自CSDN。

0 人点赞