阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Spring实现WebService分布式事务一致性

174次阅读
没有评论

共计 6918 个字符,预计需要花费 18 分钟才能阅读完成。

1. 分布式事物

分布式事务是指操作多个数据库之间的事务,为了保证事物的一致性,一般都采用 2 阶段提交的办法实现。

这里强调下一致性要求,如果追求强一致性就只能采用 JTA 事物实现。如果是最终一致性就不需要 JTA 实现了,可以采用异步消息队列实现。我这里用的是 spring 提供的 JTA 事物,因为这是个人习惯。

2. 服务端实现与配置

服务端采用 CXF 写 webservice 实现,关于 webservice 的实现与配置可以自行百度实现。我在服务端写了多个配置文件,其中一个是 webservice 的发布文件,一个是实现 DAO 层的配置,这里是不需要声明事物和对应切面的,但是一定要配置支持 XA 的数据源。JTA 事物的配置在客户端实现。我项目里数据源采用阿里的 druid。服务端的结果通过 json 传递给客户端。

服务端部分配置如下:

  <bean id=”helloServiceBean” class=”com.liuyu.service.impl.HelloServiceImpl”/>
  <jaxws:server id=”helloService” serviceClass=”com.liuyu.service.HelloServiceI” address=”/Hello”>
  <jaxws:serviceBean>                 
    <ref bean=”helloServiceBean”/>   
  </jaxws:serviceBean>
    </jaxws:server>
 3. 客户端测试
  客户端部分配置文件如下:
    <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=”300″ />
  </bean>
  <!– JTA 事务管理器 –>
  <bean id=”springTransactionManager”
  class=”org.springframework.transaction.jta.JtaTransactionManager”>
  <property name=”transactionManager” ref=”atomikosTransactionManager” />
  <property name=”userTransaction” ref=”atomikosUserTransaction” />
  </bean>
  <!– 事务管理 –>
  <tx:advice id=”txAdvice” transaction-manager=”springTransactionManager”>
  <tx:attributes>
  <tx:method name=”save*” propagation=”REQUIRED”/>
  <tx:method name=”add*” propagation=”REQUIRED”/>
  <tx:method name=”create*” propagation=”REQUIRED”/>
  <tx:method name=”insert*” propagation=”REQUIRED”/>
  <tx:method name=”update*” propagation=”REQUIRED”/>
  <tx:method name=”delete*” propagation=”REQUIRED”/>
  <tx:method name=”*” read-only=”true” />
  </tx:attributes>
  </tx:advice>
  <aop:config proxy-target-class=”true”>
  <aop:advisor advice-ref=”txAdvice” pointcut=”execution(* com.liuyu.test..*.*(..))” />
  </aop:config>
 
  客户端实现类部分如下:
 @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations = { “classpath*:applicationContext-client.xml”})
  @Transactional
  @TransactionConfiguration(defaultRollback = false)
  public class TestClient {
  @Autowired
  private HelloServiceI service;
  @Autowired
  private DemoServiceI demoService;
  @Test
  public void saveInfo() {
    service.insertHello(“2222”, “kkkkk”);
    demoService.insertHello(“2222”, “jjj”);
  }
  //@Test
  public void queryAllXA() {
    String str = demoService.queryAll();
    List<HashMap<String, Object>> list=JSON.parseObject(str, new TypeReference<List<HashMap<String,Object>>>(){});
    for(Map<String, Object> m:list){
    System.out.println(m.get(“id”).toString()+”  “+m.get(“username”).toString());
    }
  }
  }
  测试结果如下:
 [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING core version: 3.9.3
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.automatic_resource_registration = true
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.client_demarcation = false
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.threaded_2pc = false
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.serial_jta_transactions = true
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.serializable_logging = true
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.log_base_dir = .\
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.max_actives = 50
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.checkpoint_interval = 500
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.enable_logging = true
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.output_dir = .\
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.log_base_name = tmlog
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.max_timeout = 300000
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.tm_unique_name = 192.168.135.100.tm
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING java.naming.factory.initial = com.sun.jndi.rmi.registry.RegistryContextFactory
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING java.naming.provider.url = rmi://localhost:1099
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.service = com.atomikos.icatch.standalone.UserTransactionServiceFactory
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.force_shutdown_on_vm_exit = false
  [com.atomikos.icatch.config.imp.AbstractUserTransactionService]USING com.atomikos.icatch.default_jta_timeout = 10000
  [org.springframework.transaction.jta.JtaTransactionManager]Using JTA UserTransaction: com.atomikos.icatch.jta.UserTransactionImp@101b7cf
  [org.springframework.transaction.jta.JtaTransactionManager]Using JTA TransactionManager: com.atomikos.icatch.jta.UserTransactionManager@1cab519
  一月 20, 2015 4:44:56 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
  信息: Creating Service {http://service.liuyu.com/}HelloServiceIService from class com.liuyu.service.HelloServiceI
  一月 20, 2015 4:44:57 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
  信息: Creating Service {http://service.demo.liuyu.com/}DemoServiceIService from class com.liuyu.demo.service.DemoServiceI
  [com.atomikos.icatch.imp.thread.TaskManager]THREADS: using JDK thread pooling…
  [com.atomikos.icatch.imp.BaseTransactionManager]createCompositeTransaction (300000): created new ROOT transaction with id 192.168.135.100.tm0000100002
  [org.springframework.test.context.transaction.TransactionContext]Began transaction (1) for test context [DefaultTestContext@f2ed42 testClass = TestClient, testInstance = com.liuyu.test.TestClient@b691c6, testMethod = saveInfo@TestClient, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1c63a8 testClass = TestClient, locations = ‘{classpath*:applicationContext-client.xml}’, classes = ‘{}’, contextInitializerClasses = ‘[]’, activeProfiles = ‘{}’, propertySourceLocations = ‘{}’, propertySourceProperties = ‘{}’, contextLoader = ‘org.springframework.test.context.support.DelegatingSmartContextLoader’, parent = [null]]]; transaction manager [org.springframework.transaction.jta.JtaTransactionManager@1d2d7c9]; rollback [false]
  [com.atomikos.icatch.imp.CompositeTransactionImp]commit() done (by application) of transaction 192.168.135.100.tm0000100002

Struts2 整合 Spring 方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm

基于 Spring 设计并实现 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm

Spring-3.2.4 + Quartz-2.2.0 集成实例 http://www.linuxidc.com/Linux/2013-10/91524.htm

使用 Spring 进行单元测试 http://www.linuxidc.com/Linux/2013-09/89913.htm

运用 Spring 注解实现 Netty 服务器端 UDP 应用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm

Spring 3.x 企业应用开发实战 PDF 完整高清扫描版 + 源代码 http://www.linuxidc.com/Linux/2013-10/91357.htm

Spring 的详细介绍 :请点这里
Spring 的下载地址 :请点这里 

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计6918字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中