Mysql当前分布式事务只支持Innodb存储引擎。1个分布式事务由多个行为在不同的数据库上执行,1个分布式事务的执行成功意味着相关数据库上的行为执行均成功。
使用分布式事务的应用程序设计1个或多个资源管理器和一个事务管理器。
资源管理器(RM):用户提供通向事务的途径。数据库服务器是一个种资源管理器。该管理器必须提交or回滚由RM管理的事务。
事务管理器(TM):用于协调作为一个分布式事务的一部分事务。
要执行一个分布式事务,必须知道这个分布式事涉及了哪些资源管理器,并且把每个资源管理器的事务执行到事务可以被提交或回滚。根据每个资源管理报告的有关的执行情况的内容,这些分支事务必须作为一个原子性操作全部提交或回滚。
在第二阶段,TM告知RMs是否要提交或回滚。如果在预备分支时,所有的分支指示他们将能够提交,则所有的分支被告知要提交。如果在预备时,有任何分支指示它将不能提交,则所有分支被告之回滚。
分布式的语法:
XA START xid ,用来唯一标识一个分布式事务。
XA END xid
XA PRERARE xid
XA COMMIT xid
XA ROLLBACK xid
XA RECOVER
--------------------分布式事务详解--------------------------
分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持。如果使用WAS的JTA支持,把它的属性改为WebSphere对应的TransactionManager。
在tomcat下,是没有分布式事务的,不过可以借助于第三方软件jotm(Java Open Transaction Manager )和AtomikosTransactionsEssentials实现,在spring中分布式事务是通过jta(jotm,atomikos)来进行实现。
1、http://jotm.objectweb.org/
2、http://www.atomikos.com/Main/TransactionsEssentials
一、使用JOTM例子
(1) Dao及实现
GenericDao接口:
- public interface GenericDao {
- public int save(String ds, String sql, Object[] obj) throws Exception;
- public int findRowCount(String ds, String sql);
- }
GenericDaoImpl 实现:
- public class GenericDaoImpl implements GenericDao{
- private JdbcTemplate jdbcTemplateA;
- private JdbcTemplate jdbcTemplateB;
- public void setJdbcTemplateA(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplateA = jdbcTemplate;
- }
- public void setJdbcTemplateB(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplateB = jdbcTemplate;
- }
- public int save(String ds, String sql, Object[] obj) throws Exception{
- if(null == ds || "".equals(ds)) return -1;
- try{
- if(ds.equals("A")){
- return this.jdbcTemplateA.update(sql, obj);
- }else{
- return this.jdbcTemplateB.update(sql, obj);
- }
- }catch(Exception e){
- e.printStackTrace();
- throw new Exception("执行" + ds + "数据库时失败!");
- }
- }
- public int findRowCount(String ds, String sql) {
- if(null == ds || "".equals(ds)) return -1;
- if(ds.equals("A")){
- return this.jdbcTemplateA.queryForInt(sql);
- }else{
- return this.jdbcTemplateB.queryForInt(sql);
- }
- }
- }
(2) Service及实现
UserService 接口:
- public interface UserService {
- public void saveUser() throws Exception;
- }
UserServiceImpl 实现:
- public class UserServiceImpl implements UserService{
- private GenericDao genericDao;
- public void setGenericDao(GenericDao genericDao) {
- this.genericDao = genericDao;
- }
- public void saveUser() throws Exception {
- String userName = "user_" + Math.round(Math.random()*10000);
- System.out.println(userName);
- StringBuilder sql = new StringBuilder();
- sql.append(" insert into t_user(username, gender) values(?,?); ");
- Object[] objs = new Object[]{userName,"1"};
- genericDao.save("A", sql.toString(), objs);
- sql.delete(0, sql.length());
- sql.append(" insert into t_user(name, sex) values(?,?); ");
- objs = new Object[]{userName,"男的"};//值超出范围
- genericDao.save("B", sql.toString(), objs);
- }
- }
(3) applicationContext-jotm.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
- <description>springJTA</description>
- <!--指定Spring配置中用到的属性文件-->
- <bean id="propertyConfig"
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:jdbc.properties</value>
- </list>
- </property>
- </bean>
- <!-- JOTM实例 -->
- <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">
- <property name="defaultTimeout" value="500000"/>
- </bean>
- <!-- JTA事务管理器 -->
- <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
- <property name="userTransaction" ref="jotm" />
- </bean>
- <!-- 数据源A -->
- <bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
- <property name="dataSource">
- <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
- <property name="transactionManager" ref="jotm"/>
- <property name="driverName" value="${jdbc.driver}"/>
- <property name="url" value="${jdbc.url}"/>
- </bean>
- </property>
- <property name="user" value="${jdbc.username}"/>
- <property name="password" value="${jdbc.password}"/>
- </bean>
- <!-- 数据源B -->
- <bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
- <property name="dataSource">
- <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
- <property name="transactionManager" ref="jotm"/>
- <property name="driverName" value="${jdbc2.driver}"/>
- <property name="url" value="${jdbc2.url}"/>
- </bean>
- </property>
- <property name="user" value="${jdbc2.username}"/>
- <property name="password" value="${jdbc2.password}"/>
- </bean>
- <bean id = "jdbcTemplateA"
- class = "org.springframework.jdbc.core.JdbcTemplate">
- <property name = "dataSource" ref="dataSourceA"/>
- </bean>
- <bean id = "jdbcTemplateB"
- class = "org.springframework.jdbc.core.JdbcTemplate">
- <property name = "dataSource" ref="dataSourceB"/>
- </bean>
- <!-- 事务切面配置 -->
- <aop:config>
- <aop:pointcut id="pointCut"
- expression="execution(* com.logcd.service..*.*(..))"/><!-- 包及其子包下的所有方法 -->
- <aop:advisor pointcut-ref="pointCut" advice-ref="txAdvice"/>
- <aop:advisor pointcut="execution(* *..common.service..*.*(..))" advice-ref="txAdvice"/>
- </aop:config>
- <!-- 通知配置 -->
- <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">
- <tx:attributes>
- <tx:method name="delete*" rollback-for="Exception"/>
- <tx:method name="save*" rollback-for="Exception"/>
- <tx:method name="update*" rollback-for="Exception"/>
- <tx:method name="find*" read-only="true" rollback-for="Exception"/>
- </tx:attributes>
- </tx:advice>
- <bean id="genericDao" class="com.logcd.dao.impl.GenericDaoImpl" autowire="byName"> </bean>
- <bean id="userService" class="com.logcd.service.impl.UserServiceImpl" autowire="byName"> </bean>
- </beans>
(4) 测试
- public class TestUserService{
- private static UserService userService;
- @BeforeClass
- public static void init(){
- ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-jotm.xml");
- userService = (UserService)app.getBean("userService");
- }
- @Test
- public void save(){
- System.out.println("begin...");
- try{
- userService.saveUser();
- }catch(Exception e){
- System.out.println(e.getMessage());
- }
- System.out.println("finish...");
- }
- }
二、关于使用atomikos实现
(1) 数据源配置
- <bean id="dataSourceA" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">
- <property name="uniqueResourceName">
- <value>${datasource.uniqueResourceName}</value>
- </property>
- <property name="xaDataSourceClassName">
- <value>${database.driver_class}</value>
- </property>
- <property name="xaDataSourceProperties">
- <value>URL=${database.url};user=${database.username};password=${database.password}</value>
- </property>
- <property name="exclusiveConnectionMode">
- <value>${connection.exclusive.mode}</value>
- </property>
- <property name="connectionPoolSize">
- <value>${connection.pool.size}</value>
- </property>
- <property name="connectionTimeout">
- <value>${connection.timeout}</value>
- </property>
- <property name="validatingQuery">
- <value>SELECT 1</value>
- </property>
- </bean>
(2)、事务配置
- <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
- init-method="init" destroy-method="close">
- <property name="forceShutdown" value="true"/>
- </bean>
- <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
- <property name="transactionTimeout" value="${transaction.timeout}"/>
- </bean>
- <!-- JTA事务管理器 -->
- <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
- <property name="transactionManager" ref="atomikosTransactionManager"/>
- <property name="userTransaction" ref="atomikosUserTransaction"/>
- </bean>
- <!-- 事务切面配置 -->
- <aop:config>
- <aop:pointcut id="serviceOperation" expression="execution(* *..service*..*(..))"/>
- <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
- </aop:config>
- <!-- 通知配置 -->
- <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
- <tx:attributes>
- <tx:method name="*" rollback-for="Exception"/>
- </tx:attributes>
- </tx:advice>
有关JTA
JTA全称为Java Transaction API,顾名思义JTA定义了一组统一的事务编程的接口,这些接口如下:
XAResource
XAResource接口是对实现了X/Open CAE规范的资源管理器 (Resource Manager,数据库就是典型的资源管理器) 的抽象,它由资源适配器 (Resource Apdater) 提供实现。XAResource是支持事务控制的核心。
Transaction
Transaction接口是一个事务实例的抽象,通过它可以控制事务内多个资源的提交或者回滚。二阶段提交过程也是由Transaction接口的实现者来完成的。
TransactionManager
托管模式 (managed mode) 下,TransactionManager接口是被应用服务器调用,以控制事务的边界的。
UserTransaction
非托管模式 (non-managed mode) 下,应用程序可以通过UserTransaction接口控制事务的边界
托管模式下的事务提交场景
注意:在上图中3和5的步骤之间省略了应用程序对资源的操作 (如CRUD)。另外,应用服务器什么时机 enlistResource,又是什么时候delistResource呢?这在后文中会解释。
有关JCA
下图为JCA的架构图
中间涉及元素说明如下:
1)Enterprise Information System
简称EIS,在JTA中它又被称为资源管理器。典型的EIS有数据库,事务处理系统(Transaction Processing System),ERP系统。
2)Resource Adapter
资源适配器(Resource Adaper)是JCA的关键。要想把不同的EIS整合(或者连接)到J2EE运行环境中,就必须为每个EIS提供资源适配器,它会将将EIS适配为一个具备统一编程接口的资源 (Resource) 。这个统一编程接口就是上图中的System Contracts和Client API。下面的UML类图将完美诠释资源适配器。
3)Application Server
应用服务器 (Application Server) 通过System Contracts来管理对EIS的安全、事务、连接等。典型的应用服务器有JBoss、JOnAS、Geronimo、GlassFish等。
4)Application Component
应用组件 (Application Component) ,它封装了应用业务逻辑,像对资源的访问和修改。典型的应用组件就是EJB。
更多细节请参见:
Sun Microsystems Inc.J2EE Connector Architecture 1.5
http://www.ibm.com/developerworks/cn/java/j-lo-jta/
http://blog.csdn.net/ithomer/article/details/10859235
相关推荐
为了解决大家在实施分布式服务化架构过程中关于分布式事务问题的困扰,本教程将基于支付系统真实业务中的经典场景来对“可靠消息的最终一致性方案”、“TCC两阶段型方案”和“最大努力通知型方案”这3种柔性事务解决...
分布式事务是数据库管理中的一种复杂操作,特别是在大型的互联网平台和分布式系统中不可或缺。它涉及到在多台机器或多个服务之间协调数据操作,以保证数据的一致性和完整性。分布式事务的出现是由于单一数据库无法...
分布式、事务、常用解决方案、案例分析
以上就是Java分布式服务开发中关于分布式事务的核心知识点。通过深入理解并灵活运用这些概念和技术,开发者可以构建出更健壮、可靠的分布式系统。为了更全面地学习分布式事务,可以参考“分布式事务专题.pdf”文档,...
本资源包提供了关于LCN框架的全面介绍,包括PPT讲解、教学视频以及实际项目整合的demo,非常适合对分布式事务感兴趣的开发者学习和实践。 首先,分布式事务是指跨越多个数据库或者存储系统的事务处理,其目标是确保...
为了解决大家在实施分布式服务化架构过程中关于分布式事务问题的困扰,本教程将基于支付系统真实业务中的经典场景来对“可靠消息的最终一致性方案”、“TCC两阶段型方案”和“最大努力通知型方案”这3种柔性事务解决...
本压缩包"rocketmq4.3 分布式事务-rocketmqTransaction.zip"可能包含了RocketMQ 4.3版本关于分布式事务的相关源码和示例,方便开发者深入理解和学习。 分布式事务是分布式系统中一个关键且复杂的问题,它旨在确保在...
本资料“分布式事务的一种实现方式状态流转共5页.pdf.zip”似乎提供了关于分布式事务状态流转的具体实现方法。在这个讨论中,我们将深入探讨分布式事务的原理、状态流转模型以及其在实际应用中的挑战与解决方案。 ...
在这个"Java编程代码-分布式事务-源代码+讲义+资料"的压缩包中,我们可以期待深入学习关于分布式事务的理论与实践。 首先,分布式事务的核心目标是实现ACID(原子性、一致性、隔离性和持久性)特性,这是数据库事务...
本文的目的是要提供一个关于的Java事务处理API(JTA)的高级的概述,以及与分布式事务相关的内容。一个事务处理定义了一个工作逻辑单元,要么彻底成功要么不产生任何结果。 一个分布式事务处理只是一个在两个或更多...
程立在2008年2月的中国软件大会上发布的关于分布式事务的PPT,被认为是分布式开发者必读的经典之作。他的演讲中提到的分布式事务处理的知识点,主要包括以下几个方面: 1. 分布式事务的基本概念:在大规模SOA系统中...
这事关于分布式事务的处理视频教程,内容很详细,网上绝大多数都要解压码,这个视频教程是本人在某宝商花重金购买的哦,绝对不加密,而且里面还包含相关的课件。
标题《基于非阻塞的分布式事务提交协议的实现》和描述提到了关于分布式事务提交协议的最新研究和实现,具体内容中介绍了两阶段提交(2PC)和三阶段提交(3PC)协议的缺点,并提出了一种新的基于非阻塞的两阶段提交协议...
这是一个关于使用SpringBoot和Seata构建分布式事务管理系统的计算机课程大作业项目。在这个项目中,学生将学习如何在微服务架构中处理分布式环境中的事务一致性问题。以下是该项目涉及的主要知识点和详细说明: **1...
DotNet的Com+分布式事务处理的配置与调试 分别讲述sql2000及sql2005中关于分布式事务处理所需的配置。 附有代码。 该文档有47页,内容丰富
分布式事务在现代微服务架构中扮演着至关重要的角色,它确保了在多个服务间的数据一致性。SpringCloud作为主流的微服务框架,提供了多种处理分布式事务的解决方案,其中之一就是LCN(Local Call Notification)。LCN...
分布式事务在现代大规模分布式系统中扮演着至关重要的角色,它确保了在多个节点间的数据一致性。两阶段提交(Two-Phase Commit, 2PC)是分布式事务中常见的一种协调协议,用于解决分布式环境下数据的一致性问题。这...
这事关于分布式事务的处理视频教程,内容很详细,网上绝大多数都要解压码,这个视频教程是本人在某宝商花重金购买的哦,绝对不加密,而且里面还包含相关的课件。
《Sharding-JDBC分布式事务应用》是一篇关于Java领域中如何利用Sharding-JDBC实现分布式事务的专题讨论。Sharding-JDBC是阿里巴巴开源的一款轻量级数据库中间件,它为Java开发者提供了一种透明化的数据分片解决方案...
收集的一些关于在现代开发运行环境(微服务等)下,解决分布式事务的论文。包括古老的saga论文,Atomikos公司Guy同学的一些想法及其它。