<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Aaronlong31

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      12 Posts :: 3 Stories :: 17 Comments :: 0 Trackbacks
    ?

    使用平臺:

    1.??? Mysql 5.0.8

    2.??? ibatis 2.3.4

    3.??? spring 2.5

    4.??? eclipse 3.3

    完成賬戶的轉賬功能,在出現異常時回滾。由spring管理各個類之間的關系和事務處理。

    1. 首先建立兩個數據庫,一個在本機上,一個在遠端機上,腳本分別如下
      ?1DROP?DATABASE?IF?EXISTS?testdb_a_zhanglong;
      ?2
      ?3CREATE?DATABASE?testdb_a_zhanglong;
      ?4
      ?5USE?testdb_a_zhanglong;
      ?6
      ?7CREATE?TABLE?Account(
      ?8????aid????????INT????????AUTO_INCREMENT,
      ?9????owner????????VARCHAR(20)????NOT?NULL,
      10????balance????????Float(10,3)????DEFAULT?0.0,
      11????PRIMARY?KEY(aid)
      12);
      13
      14INSERT?INTO?Account?(owner,balance)?VALUES?('zhanglong',10000.00);
      15
      ?1DROP?DATABASE?IF?EXISTS?testdb_b_zhanglong;
      ?2
      ?3CREATE?DATABASE?testdb_b_zhanglong;
      ?4
      ?5USE?testdb_b_zhanglong;
      ?6
      ?7CREATE?TABLE?Account(
      ?8????aid????????INT????????AUTO_INCREMENT,
      ?9????owner????????VARCHAR(20)????NOT?NULL,
      10????balance????????Float(10,3)????DEFAULT?0.0,
      11????PRIMARY?KEY(aid)
      12);
      13
      14INSERT?INTO?Account?(owner,balance)?VALUES?('zhengtao',10000.00);
      15

      在這里兩個數據庫是完全一樣的,是為了方便起見

    2. 建立AccountJavaBean
      1package?com.aaron.atomikos.domain;
      2
      3public?class?Account?{
      4
      5????private?int?accountId;
      6????private?String?owner;
      7????private?float?balance;
      8}

      9
    3. 建立業務層接口AccountService
      ?1package?com.aaron.atomikos.service;
      ?2import?com.aaron.atomikos.domain.Account;
      ?3public?interface?AccountService?{
      ?4????void?addAccount(Account?account);
      ?5????
      ?6????/**
      ?7?????*?轉賬
      ?8?????*?@param?ida
      ?9?????*?@param?idb
      10?????*?@param?amount
      11?????*?@return
      12?????*/

      13????boolean?transfer(int?ida,int?idb,float?amount);?
      14????
      15????Account?getAccountById(int?id);
      16}

      17
      ?
    4. 建立業務層接口實現類AccountServiceImpl
      ?1package?com.aaron.atomikos.service.impl;
      ?2import?com.aaron.atomikos.dao.AccountDao;
      ?3import?com.aaron.atomikos.domain.Account;
      ?4import?com.aaron.atomikos.service.AccountService;
      ?5public?class?AccountServiceImpl?implements?AccountService?{
      ?6
      ?7????//?數據庫a的Dao類
      ?8????private?AccountDao?accountaDao;
      ?9????//?數據庫b的Dao類
      10????private?AccountDao?accountbDao;
      11????public?AccountDao?getAccountbDao()?{
      12????????return?accountbDao;
      13????}

      14????public?void?setAccountbDao(AccountDao?accountbDao)?{
      15????????this.accountbDao?=?accountbDao;
      16????}

      17????public?AccountDao?getAccountDao()?{
      18????????return?accountaDao;
      19????}

      20????public?void?setAccountaDao(AccountDao?accountaDao)?{
      21????????this.accountaDao?=?accountaDao;
      22????}

      23????@Override
      24????public?void?addAccount(Account?account)?{
      25????????accountaDao.insertAccount(account);
      26????}

      27
      28????@Override
      29????public?boolean?transfer(int?ida,?int?idb,?float?amount)?{
      30????????boolean?isSuccess?=?false;
      31
      32????????Account?accounta?=?new?Account();
      33????????Account?accountb?=?new?Account();
      34
      35????????//檢查賬戶是否存在
      36????????if?(!accountaDao.isExists(ida)?||?!accountbDao.isExists(idb))?{
      37????????????throw?new?RuntimeException("賬戶"?+?ida?+?""?+?idb?+?"不存在");
      38????????}

      39????????
      40????????//得到賬戶余額
      41????????float?balancea?=?accountaDao.getBalance(ida);
      42????????float?balanceb?=?accountbDao.getBalance(idb);
      43????????if?(balancea?<?amount)?{
      44????????????throw?new?RuntimeException("賬戶"?+?ida?+?"的余額不足!");
      45????????}

      46????????
      47????????//轉賬
      48????????accounta.setAccountId(ida);
      49????????accountb.setAccountId(idb);
      50????????accounta.setBalance(balancea?-?amount);
      51????????accountb.setBalance(balanceb?+?amount);
      52
      53????????accountaDao.updateAccount(accounta);
      54
      55????????//兩次更新之間如果跑出異常,則會回滾操作
      56????????//?if(true){
      57????????//?throw?new?RuntimeException();
      58????????//?}
      59
      60????????accountbDao.updateAccount(accountb);
      61????????isSuccess?=?true;
      62????????return?isSuccess;
      63????}

      64
      65????@Override
      66????public?Account?getAccountById(int?id)?{
      67????????return?accountaDao.selectAccountById(id);
      68????}

      69}

      70
  • 建立DAO層AccountDao,繼承自spring的SqlMapClientDaoSupport,這里為了簡單起見,沒有使用接口,直接寫了具體實現類
    ?1package?com.aaron.atomikos.dao;
    ?2
    ?3import?org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
    ?4
    ?5import?com.aaron.atomikos.domain.Account;
    ?6
    ?7public?class?AccountDao?extends?SqlMapClientDaoSupport?{
    ?8
    ?9????/**
    10?????*?插入賬戶
    11?????*?
    12?????*?@param?account
    13?????*/

    14????public?void?insertAccount(Account?account)?{
    15????????getSqlMapClientTemplate().insert("Account.insertAccount",?account);
    16????}

    17
    18????/**
    19?????*?根據id刪除賬戶
    20?????*?
    21?????*?@param?id
    22?????*/

    23????public?void?deleteAccountById(int?id)?{
    24????????getSqlMapClientTemplate().delete("Account.deleteAccountById",?id);
    25????}

    26
    27????/**
    28?????*?更新賬戶余額
    29?????*?
    30?????*?@param?account
    31?????*/

    32????public?void?updateAccount(Account?account)?{
    33????????getSqlMapClientTemplate().update("Account.updateBalance",?account);
    34????}

    35
    36????/**
    37?????*?根據id查找賬戶
    38?????*?
    39?????*?@param?id
    40?????*?@return
    41?????*/

    42????public?Account?selectAccountById(int?id)?{
    43????????return?(Account)?getSqlMapClientTemplate().queryForObject(
    44????????????????"Account.selectAccountById",?id);
    45????}

    46
    47????/**
    48?????*?根據賬戶編號得到余額
    49?????*?
    50?????*?@param?idb
    51?????*?@return
    52?????*/

    53????public?float?getBalance(int?idb)?{
    54????????return?Float.parseFloat(getSqlMapClientTemplate().queryForObject(
    55????????????????"Account.selectBalance",?idb).toString());
    56????}

    57
    58????/**
    59?????*?判斷賬戶是否存在
    60?????*?
    61?????*?@param?ida
    62?????*?@return
    63?????*/

    64????public?boolean?isExists(int?ida)?{
    65????????return?(Integer)?getSqlMapClientTemplate().queryForObject(
    66????????????????"Account.selectCount",?ida)?>?0???true?:?false;
    67????}

    68}
  • 編寫iBATIS的sql映射文件Account.xml
    ?1<?xml?version="1.0"?encoding="UTF-8"?>
    ?2<!DOCTYPE?sqlMap?PUBLIC?"-//ibatis.apache.org//DTD?SQL?Map?2.0//EN"?"http://ibatis.apache.org/dtd/sql-map-2.dtd"?>
    ?3<sqlMap?namespace="Account">
    ?4????<typeAlias?alias="Account"?type="com.aaron.atomikos.domain.Account"?/>
    ?5????<select?id="selectAccountById"?parameterClass="int"?resultClass="Account">
    ?6????????select?*?from?Account?where?aid?=?#value#
    ?7????</select>
    ?8????
    ?9????<select?id="selectBalance"?parameterClass="int"?resultClass="float">
    10????????select?balance?from?Account?where?aid?=?#value#
    11????</select>
    12????
    13????<select?id="selectCount"?parameterClass="int"?resultClass="int">
    14????????select?count(*)?from?Account?where?aid?=?#value#
    15????</select>
    16????
    17????<update?id="updateBalance"?parameterClass="Account">
    18????????update?Account?set?balance?=?#balance#?where?aid?=?#accountId#
    19????</update>
    20????
    21????<insert?id="insertAccount"?parameterClass="Account">
    22????????insert?into?Account?(owner,balance)?values?(#owner#,#balance#);
    23????</insert>
    24</sqlMap>
    還要建立兩個ibatis的配置文件sql-map-config_A.xml和sql-map-config_B.xml,由于有兩個數據庫,所以要建兩個。具體不列出。
  • 編寫spring的applicationContext.xml
    ??1<?xml?version="1.0"?encoding="UTF-8"?>
    ??2<beans?xmlns="http://www.springframework.org/schema/beans"
    ??3????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    ??4????xmlns:jee="http://www.springframework.org/schema/jee"
    ??5????xmlns:aop="http://www.springframework.org/schema/aop"
    ??6????xmlns:tx="http://www.springframework.org/schema/tx"
    ??7????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd?
    ??8?????????????????????http://www.springframework.org/schema/jee?http://www.springframework.org/schema/jee/spring-jee-2.0.xsd?
    ??9?????????????????????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.0.xsd?
    ?10?????????????????????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    ?11
    ?12????<!--?讀取數據庫連接配置文件?-->
    ?13????<bean?id="propertyConfig"
    ?14????????class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    ?15????????<property?name="locations">
    ?16????????????<list>
    ?17????????????????<value>classpath:jdbc.properties</value>
    ?18????????????</list>
    ?19????????</property>
    ?20????</bean>
    ?21
    ?22????<!--?數據源A(使用com.atomikos.jdbc.AtomikosDataSourceBean作為數據源)?-->
    ?23????<bean?id="datasourceA"
    ?24????????class="com.atomikos.jdbc.AtomikosDataSourceBean"?init-method="init"
    ?25????????destroy-method="close">
    ?26????????<property?name="uniqueResourceName">
    ?27????????????<value>mysql/db_a</value>
    ?28????????</property>
    ?29????????<property?name="xaDataSourceClassName">
    ?30????????????<value>${jdbc.driverClassName}</value>
    ?31????????</property>
    ?32????????<property?name="poolSize">
    ?33????????????<value>3</value>
    ?34????????</property>
    ?35?????????<property?name="xaProperties">
    ?36?????????????<props>
    ?37?????????????????<prop?key="url">${jdbc.url}</prop>
    ?38?????????????????<prop?key="user">${jdbc.username}</prop>
    ?39?????????????????<prop?key="password">${jdbc.password}</prop>
    ?40?????????????</props>
    ?41?????????</property>
    ?42????</bean>
    ?43
    ?44????<!--?數據源B(使用com.atomikos.jdbc.SimpleDataSourceBean作為數據源)?-->
    ?45????<bean?id="datasourceB"
    ?46????????class="com.atomikos.jdbc.SimpleDataSourceBean"?init-method="init"
    ?47????????destroy-method="close">
    ?48????????<property?name="uniqueResourceName">
    ?49????????????<value>mysql/db_b</value>
    ?50????????</property>
    ?51????????<property?name="xaDataSourceClassName">
    ?52????????????<value>${jdbc2.driverClassName}</value>
    ?53????????</property>
    ?54????????<property?name="xaDataSourceProperties">
    ?55????????????<value>user=${jdbc2.username};password=${jdbc2.password};url=${jdbc2.url};encoding=${jdbc2.encoding}</value>
    ?56????????</property>
    ?57????????<property?name="exclusiveConnectionMode">
    ?58????????????<value>true</value>
    ?59????????</property>
    ?60????????<property?name="validatingQuery">
    ?61????????????<value>SELECT?1</value>
    ?62????????</property>
    ?63????????<property?name="connectionPoolSize">
    ?64????????????<value>3</value>
    ?65????????</property>
    ?66????</bean>
    ?67
    ?68????<!--?配置atomikos的事務管理器?-->
    ?69????<bean?id="atomikosTransactionManager"
    ?70????????class="com.atomikos.icatch.jta.UserTransactionManager"
    ?71????????init-method="init"?destroy-method="close">
    ?72????????<property?name="forceShutdown"?value="true"?/>
    ?73????</bean>
    ?74
    ?75????<bean?id="atomikosUserTransaction"
    ?76????????class="com.atomikos.icatch.jta.UserTransactionImp">
    ?77????????<property?name="transactionTimeout"?value="300"?/>
    ?78????</bean>
    ?79
    ?80????<!--?spring的JTA事務管理器?-->
    ?81????<bean?id="springTransactionManager"
    ?82????????class="org.springframework.transaction.jta.JtaTransactionManager">
    ?83????????<property?name="transactionManager"
    ?84????????????ref="atomikosTransactionManager"?/>
    ?85????????<property?name="userTransaction"?ref="atomikosUserTransaction"?/>
    ?86????</bean>
    ?87
    ?88????<!--?通知配置?-->
    ?89????<tx:advice?id="txAdvice"
    ?90????????transaction-manager="springTransactionManager">
    ?91????????<tx:attributes>
    ?92????????????<tx:method?name="delete*"?rollback-for="Exception"?/>
    ?93????????????<tx:method?name="save*"?rollback-for="Exception"?/>
    ?94????????????<tx:method?name="update*"?rollback-for="Exception"?/>
    ?95????????????<tx:method?name="*"?read-only="true"
    ?96????????????????rollback-for="Exception"?/>
    ?97????????</tx:attributes>
    ?98????</tx:advice>
    ?99
    100????<!--?事務切面配置?-->
    101????<aop:config>
    102????????<aop:pointcut?id="serviceOperation"
    103????????????expression="execution(*?*..service*..*(..))"?/>
    104????????<aop:advisor?advice-ref="txAdvice"
    105????????????pointcut-ref="serviceOperation"?/>
    106????</aop:config>
    107
    108????<!--?根據dataSourceA和sql-map-config_A.xml創建一個SqlMapClientA?-->
    109????<bean?id="sqlMapClientA"
    110????????class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    111????????<property?name="dataSource">
    112????????????<ref?local="datasourceA"?/>
    113????????</property>
    114????????<property?name="configLocation">
    115????????????<value>classpath:/sql-map-config_A.xml</value>
    116????????</property>
    117????</bean>
    118
    119????<!--?根據dataSourceB和sql-map-config_B.xml創建一個SqlMapClientB?-->
    120????<bean?id="sqlMapClientB"
    121????????class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    122????????<property?name="dataSource">
    123????????????<ref?local="datasourceB"?/>
    124????????</property>
    125????????<property?name="configLocation">
    126????????????<value>classpath:/sql-map-config_B.xml</value>
    127????????</property>
    128????</bean>
    129
    130????<!--根據sqlMapClientA創建一個SqlMapClientTemplate的模版類實例sqlMapClientTemplateA-->
    131????<bean?id="sqlMapClientTemplateA"
    132????????class="org.springframework.orm.ibatis.SqlMapClientTemplate">
    133????????<property?name="sqlMapClient"?ref="sqlMapClientA"?/>
    134????</bean>
    135
    136????<!--根據sqlMapClientB創建一個SqlMapClientTemplate的模版類實例sqlMapClientTemplateB-->
    137????<bean?id="sqlMapClientTemplateB"
    138????????class="org.springframework.orm.ibatis.SqlMapClientTemplate">
    139????????<property?name="sqlMapClient"?ref="sqlMapClientB"?/>
    140????</bean>
    141
    142????<!--?配置DAO?-->
    143????<bean?id="accountaDao"?class="com.aaron.atomikos.dao.AccountDao">
    144????????<property?name="sqlMapClientTemplate"
    145????????????ref="sqlMapClientTemplateA"?/>
    146????</bean>
    147
    148????<bean?id="accountbDao"?class="com.aaron.atomikos.dao.AccountDao">
    149????????<property?name="sqlMapClientTemplate"
    150????????????ref="sqlMapClientTemplateB"?/>
    151????</bean>
    152
    153????<!--?配置service?-->
    154????<bean?id="accountService"
    155????????class="com.aaron.atomikos.service.impl.AccountServiceImpl">
    156????????<property?name="accountaDao"?ref="accountaDao"?/>
    157????????<property?name="accountbDao"?ref="accountbDao"?/>
    158????</bean>
    159</beans>
    在這里,我使用了兩個不同類的數據源,只是為了測試,具體配置如上。兩者設置屬性時有點差別,數據源com.atomikos.jdbc.AtomikosDataSourceBean中設置url,user,password屬性是用xaProperties這個屬性,它是個Properties類型,所以要用<props>標簽分開設置,數據源com.atomikos.jdbc.SimpleDataSourceBean中設置url,user,password屬性使用xaDataSourceProperties這個屬性,它是String類型,查看源代碼可以知道,這個類會把xaDataSourceProperties按“;”進行分割,得到user=root,password=root等幾個字符串,再將“=”兩邊的字符串分別作為屬性名和屬性值放入一個properties變量中。有一點要注意,
    1<value>user=${jdbc2.username};password=${jdbc2.password};url=${jdbc2.url};encoding=${jdbc2.encoding}</value>
    中的<value>和user=${jdbc2.username}之間不能換行,因為該類不會忽略換行,會把換行加上user當成一個字符串,之后會報錯的。
  • 編寫測試類AccountServiceTest
    ?1package?com.aaron.atomikos.test;
    ?2
    ?3import?org.springframework.context.ApplicationContext;
    ?4import?org.springframework.context.support.ClassPathXmlApplicationContext;
    ?5import?com.aaron.atomikos.service.AccountService;
    ?6import?junit.framework.Assert;
    ?7import?junit.framework.TestCase;
    ?8
    ?9public?class?AccountServiceTest?extends?TestCase?{
    10
    11????protected?static?ApplicationContext?????????????applicationContext;
    12????protected?static?AccountService?accountService;
    13????static?{
    14????????applicationContext?=?new?ClassPathXmlApplicationContext("applicationContext.xml");
    15????????accountService?=?(AccountService)?applicationContext.getBean("accountService");
    16????}

    17????
    18????public?void?testTransfer(){
    19????????int?ida?=?1;
    20????????int?idb?=?1;
    21????????Assert.assertNotNull(accountService.transfer(ida,?idb,?666));
    22????}

    23}

  • 執行,查看數據庫,成功!若將AccountserviceImpl中的拋出異常注釋去掉,則會在兩個數據庫中回滾。
  • posted on 2010-01-29 13:34 Aaronlong31 閱讀(3760) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 日韩午夜理论免费TV影院| 亚洲国产一区二区三区在线观看 | 日日躁狠狠躁狠狠爱免费视频| 亚洲男人电影天堂| 人人狠狠综合久久亚洲婷婷| 亚洲成人国产精品| 四虎永久免费影院在线| 在线看片无码永久免费视频| 无码国产精品一区二区免费vr| 一级一级毛片免费播放| 国产精品亚洲一区二区三区| 亚洲午夜无码久久久久小说| 国产免费一区二区视频| 老司机福利在线免费观看| 国产精品高清视亚洲精品| 久久精品亚洲中文字幕无码麻豆| 国产精品亚洲二区在线观看 | 亚洲最大中文字幕无码网站| 久久久久亚洲av无码专区| 亚洲线精品一区二区三区| 亚洲美女在线国产| 亚洲国产成人精品无码久久久久久综合 | 4hu四虎免费影院www| 特级毛片全部免费播放| 久久人午夜亚洲精品无码区| 亚洲中文字幕无码av| 亚洲综合校园春色| 亚洲高清中文字幕免费| 亚洲看片无码在线视频| 亚洲一区二区三区在线网站| 亚洲天堂一区二区三区四区| 亚洲乱码一二三四区国产| 亚洲国产精品久久丫| 亚洲人成毛片线播放| 亚洲丰满熟女一区二区v| 国产亚洲中文日本不卡二区| 亚洲不卡影院午夜在线观看| 亚洲精品无码人妻无码| 美国毛片亚洲社区在线观看| 国产AV无码专区亚洲AV琪琪|