在日常项目中肯定需要用到数据源,那么数据源是什么,当遇到分布式事务的场景时数据源与非分布式事务场景的数据源又有什么不同呢,在J2EE中分布式事务又是如何实现的呢,希望本文可以解答您的疑惑。
通俗来讲,数据源是存储数据的地方。例如,数据库是数据源,其他系统也可以是数据源。在J2EE里,数据源是代表物理数据存储系统的实际Java对象。通过这些对象,J2EE应用可以获取到数据库的JDBC连接。
从UML图上可以看出, CommonDaraSource 是对数据源概念的顶层抽象,约束了数据源必须实现的方法。数据源有三种类型的实现,分别是:
XA数据源指的是支持XA规范的数据源,支持分布式事务。
XA规范是一种分布式事务解决方案。X/OPEN组织定义的分布式事务处理模型(DTP),其包含3种角色和两个协议:
该模型中应用程序将一个全局事务传送到事务管理器,事务管理器将每个全局事务分解为多个分支(分支事务),并将分支事务分配给单独的资源管理器进行服务,事务管理器通过XA接口将每个分支事务与适当的资源管理器进行协调。
如果仅在同一个事务上下文中需要协调多种资源(即数据库以及消息主题或队列等等),这个事务中的所有操作都必须成功,否则所有操作都将在失败的情况下回滚。这就是XA数据源的作用。
Java事务编程接口(Java Transaction API,JTA)和Java事务服务(Java Transaction Service,JTS)为J2EE平台提供了分布式事务服务。
JTA事务是XA规范的Java实现,JTA事务有效的屏蔽了底层事务资源,使应用可以以透明的方式参与到事务处理中。分布式事务包括事务管理器和一个或多个支持XA协议的资源管理器。
JTA是面向应用或应用服务器与资源管理器的高层事务接口。
JTS是一组约定JTA中角色之间交互细节的规范。
JTA提供了以下四个接口
开发者调用UserTransaction.begin方法时,因为UserTransaction的实现类持有TransactionManager,TransactionManager充当UserTransaction和Transaction之间的桥梁,所以在调用UserTransaction的begin方法时,TransactionManager会创建Transaction事务对象,并把此对象通过ThreadLocal关联到当前线程。当调用UserTransaction其他方法时,会从当前线程取出事务对象Transaction对象,并通过Transaction对象找到与其关联的XAResource对象,然后进行commit、rollback等操作。其基本流程如以下代码:
// 创建一个Transaction,挂到当前线程上 UserTransaction userTx = null; Connection connA = null; Connection connB = null; try{ userTx.begin(); // 将Connection对应的XAResource挂到当前线程对应的Transaction connA.exec("xxx") connB.exec("xxx") // 找到Transaction关联的XAResource,让它们都提交 userTx.commit(); }catch(){ // 找到Transaction关联的XAResource,让它们都回滚 userTx.rollback(); }
本文主要介绍了数据源和XA数据源,以及分布式事务基本原理、作用和场景以及如何使用J2EE分布式事务,但这种是属于基于资源层的底层分布式事务解决方案,在业内,用来解决分布式事务的方案还有柔性事务,柔性事务包括几种类型:两阶段型、补偿型、异步确保型和最大努力通知型,有兴趣可以更深入的了解一下。
作者 | Karina Varela · Jun
翻译 | 小青菜
来源 | https://dzone.com/articles/da...
本文有spring4all技术翻译组完成,更多国外前沿知识和干货好文,欢迎关注公众号:后端面试那些事儿。
很遗憾的说,推酷将在这个月底关闭。人生海海,几度秋凉,感谢那些有你的时光。
原文 https://segmentfault.com/a/1190000023359961