最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring整合atomikos實現(xiàn)分布式事務(wù)的方法示例

 更新時間:2019年05月21日 09:26:07   作者:胖子k  
本文整合了一個spring和atomikos的demo,并且通過案例演示說明atomikos的作用,具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

Atomikos 是一個為Java平臺提供增值服務(wù)的并且開源類事務(wù)管理器,主要用于處理跨數(shù)據(jù)庫事務(wù),比如某個指令在A庫和B庫都有寫操作,業(yè)務(wù)上要求A庫和B庫的寫操作要具有原子性,這時候就可以用到atomikos。筆者這里整合了一個spring和atomikos的demo,并且通過案例演示說明atomikos的作用。

準(zhǔn)備工作

開發(fā)工具:idea

數(shù)據(jù)庫:mysql , oracle

正文

源碼地址: https://github.com/qw870602/atomikos

演示原理:通過在兩個庫的寫操作之間人為制造異常來觀察數(shù)據(jù)庫是否回滾

演示步驟:1.正常寫操作,觀察數(shù)據(jù)庫值的變化情況

                   2.在寫操作語句之間制造異常,觀察數(shù)據(jù)庫值的變化情況

項目結(jié)構(gòu)

從web.xml中可以知道,容器只加載了appliactionContext.xml,剩下的配置文件除了database.properties外都是無用文件,所以大家如果要在項目中配置的話,僅需要把appliactionContext.xml中關(guān)于atomikos的部分新增到自己項目中就OK了

appliactionContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/mvc
  http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
  <!-- 引入數(shù)據(jù)源信息的properties屬性文件 -->
  <context:property-placeholder location="classpath:database.properties" />
  <!-- XA方式 -->
  <!-- MYSQL數(shù)據(jù)庫配置 -->
  <bean id="mysqlDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close">
    <property name="uniqueResourceName" value="dataSource1"/>
    <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
    <property name="xaProperties">
      <props>
        <prop key="URL">${mysql.qa.db.url}</prop>
        <prop key="user">${mysql.qa.db.user}</prop>
        <prop key="password">${mysql.qa.db.password}</prop>
      </props>
    </property>
    <property name="minPoolSize" value="10" />
    <property name="maxPoolSize" value="100" />
    <property name="borrowConnectionTimeout" value="30" />
    <property name="maintenanceInterval" value="60" />
  </bean>

  <!-- ORACLE數(shù)據(jù)庫配置 -->
  <bean id="oracleDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close">
    <property name="uniqueResourceName" value="dataSource2"/>
    <property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
    <property name="xaProperties">
      <props>
        <prop key="URL">${oracle.qa.db.url}</prop>
        <prop key="user">${oracle.qa.db.user}</prop>
        <prop key="password">${oracle.qa.db.password}</prop>
      </props>
    </property>
    <property name="minPoolSize" value="10" />
    <property name="maxPoolSize" value="100" />
    <property name="borrowConnectionTimeout" value="30" />
    <property name="maintenanceInterval" value="60" />
  </bean>

  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--<property name="configLocation" value="classpath:mybatis-config-mysql.xml" />-->
    <property name="dataSource" ref="mysqlDataSource" />
    <property name="mapperLocations" >
      <list>
        <value>classpath*:/dao/*.xml</value>
      </list>
    </property>
  </bean>
  <bean id="sqlSessionFactoryOracle" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--<property name="configLocation" value="classpath:mybatis-config.xml" />-->
    <property name="dataSource" ref="oracleDataSource" />
    <property name="mapperLocations" >
      <list>
        <value>classpath*:/daodev/*.xml</value>
      </list>
    </property>
  </bean>

  <!-- MyBatis為不同的mapper注入sqlSessionFactory -->
  <bean id="mysqlTransactionTestDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    <property name="mapperInterface" value="com.xy.dao.MysqlTransactionTestDao" />
  </bean>
  <bean id="transactionTestDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="sqlSessionFactory" ref="sqlSessionFactoryOracle" />
    <property name="mapperInterface" value="com.xy.dao.TransactionTestDao" />
  </bean>

  <!-- 分布式事務(wù) -->
  <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>
  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="atomikosTransactionManager"/>
    <property name="userTransaction" ref="atomikosUserTransaction"/>
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager"/>
  <context:annotation-config/>
  <!--&lt;!&ndash; 自動掃描controller包下的所有類,如果@Controller注入為bean &ndash;&gt;-->
  <!--&lt;!&ndash;事務(wù)管理層&ndash;&gt;-->
  <context:component-scan base-package="com.xy" />

  <!-- 注冊攔截器 -->
  <!--<mvc:interceptors>
    <bean class="com.springmybatis.system.interceptor.MyInterceptor" />
  </mvc:interceptors>-->
</beans>

適用JUnit4進行單元測試

package com.xy.controller;

import com.xy.daodev.TransactionTestService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class TransactionTestMain extends AbstractJUnit4SpringContextTests {
  @Autowired
 private TransactionTestService transactionTestService;
 
 /**
 * 在同一事務(wù)有多個數(shù)據(jù)源
 */
 @Test
 public void multipleDataSource2() {
 transactionTestService.updateMultipleDataSource("1","1", 100L,"1.6");
 }
}

業(yè)務(wù)實現(xiàn),當(dāng)前沒有異常操作

@Service
public class TransactionTestServiceImpl implements TransactionTestService {
  @Autowired
 @Qualifier("mysqlTransactionTestDao")
 private MysqlTransactionTestDao mysqlTransactionTestDao;
 
 @Autowired
 @Qualifier("transactionTestDao")
 private TransactionTestDao transactionTestDao;
 
 /**
 * 在同一事務(wù)有多個數(shù)據(jù)源
 */
 @Override
 @Transactional
 public void updateMultipleDataSource(String deUserId, String inUserid, long money,String str) {
 // 賬戶1轉(zhuǎn)出操作
 mysqlTransactionTestDao.decreaseMoney(deUserId, money);
  //Integer.parseInt(str);
 // 賬戶2轉(zhuǎn)入操作
 transactionTestDao.increaseMoney(inUserid, money);
 
 } 

}

mysql模擬金額轉(zhuǎn)出,oracle模擬金額轉(zhuǎn)入

<update id="decreaseMoney" parameterType="java.util.Map">
  UPDATE fx1 SET amount=amount - #{1,jdbcType=BIGINT} WHERE id=#{0,jdbcType=VARCHAR}
</update>
<update id="increaseMoney">
  UPDATE fx1 SET amount=amount + #{1,jdbcType=BIGINT} WHERE id=#{0,jdbcType=VARCHAR}
</update>

mysql初始金額

oracle初始金額

執(zhí)行正常操作

mysql當(dāng)前金額

oracle當(dāng)前金額

將被屏蔽的制造異常的代碼打開

public void updateMultipleDataSource(String deUserId, String inUserid, long money,String str) {
 // 賬戶1轉(zhuǎn)出操作
 mysqlTransactionTestDao.decreaseMoney(deUserId, money);
  Integer.parseInt("skg");
 // 賬戶2轉(zhuǎn)入操作
 transactionTestDao.increaseMoney(inUserid, money);
} 

發(fā)現(xiàn)mysql和oracle的當(dāng)前金額都沒有變化,說明事務(wù)回滾成功,查看日志

發(fā)現(xiàn)控制臺打印出了異常信息,并且atomikos調(diào)用了rollback()方法,從日志也證實了回滾成功。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用java實現(xiàn)BBS論壇發(fā)送郵件過程詳解

    使用java實現(xiàn)BBS論壇發(fā)送郵件過程詳解

    這篇文章主要介紹了使用java發(fā)送郵件過程詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • java郵件亂碼的徹底解決方案

    java郵件亂碼的徹底解決方案

    在本篇文章里小編給大家整理的是關(guān)于java郵件亂碼的徹底解決方案,需要的朋友們可以學(xué)習(xí)下。
    2019-12-12
  • java?11新特性HttpClient主要組件及發(fā)送請求示例詳解

    java?11新特性HttpClient主要組件及發(fā)送請求示例詳解

    這篇文章主要為大家介紹了java?11新特性HttpClient主要組件及發(fā)送請求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • SpringBoot通過注解下載任意對象

    SpringBoot通過注解下載任意對象

    下載功能應(yīng)該是比較常見的功能了,雖然一個項目里面可能出現(xiàn)的不多,但是基本上每個項目都會有,而且有些下載功能其實還是比較繁雜的,這篇文章主要介紹了SpringBoot一個注解就能幫你下載任意對象,需要的朋友可以參考下
    2023-08-08
  • 解決SpringBoot項目讀取yml文件中值為中文時,在視圖頁面顯示亂碼

    解決SpringBoot項目讀取yml文件中值為中文時,在視圖頁面顯示亂碼

    這篇文章主要介紹了解決SpringBoot項目讀取yml文件中值為中文時,在視圖頁面顯示亂碼的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java學(xué)習(xí)之猜數(shù)字小游戲

    java學(xué)習(xí)之猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了java學(xué)習(xí)之猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • java工具類之實現(xiàn)java獲取文件行數(shù)

    java工具類之實現(xiàn)java獲取文件行數(shù)

    這篇文章主要介紹了一個java工具類,可以取得當(dāng)前項目中所有java文件總行數(shù),代碼行數(shù),注釋行數(shù),空白行數(shù),需要的朋友可以參考下
    2014-03-03
  • java實現(xiàn)文件保存到本地的方法

    java實現(xiàn)文件保存到本地的方法

    本篇文章主要介紹了java實現(xiàn)文件保存到本地的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • spring-boot-autoconfigure模塊用法詳解

    spring-boot-autoconfigure模塊用法詳解

    autoconfigure就是自動配置的意思,spring-boot通過spring-boot-autoconfigure體現(xiàn)了"約定優(yōu)于配置"這一設(shè)計原則,而spring-boot-autoconfigure主要用到了spring.factories和幾個常用的注解條件來實現(xiàn)自動配置,思路很清晰也很簡單,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Java servlet通過事件驅(qū)動進行高性能長輪詢詳解

    Java servlet通過事件驅(qū)動進行高性能長輪詢詳解

    這篇文章主要介紹了基于servlet3.0+事件驅(qū)動實現(xiàn)高性能長輪詢的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2022-06-06

最新評論

武义县| 嘉义市| 隆林| 泗水县| 寻乌县| 五指山市| 明星| 平乡县| 临泉县| 五寨县| 宣武区| 沙田区| 肇东市| 黄浦区| 平山县| 临漳县| 瓦房店市| 孟连| 乡宁县| 江川县| 连江县| 甘孜| 台中县| 布拖县| 永福县| 丰城市| 台东市| 金门县| 贡山| 奉新县| 班玛县| 富民县| 文山县| 绥中县| 井冈山市| 衡水市| 黎川县| 太仆寺旗| 自治县| 林州市| 额济纳旗|