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

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

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

    Aaronlong31

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      12 Posts :: 3 Stories :: 17 Comments :: 0 Trackbacks
    ?

    使用平臺(tái):

    1.??? Mysql 5.0.8

    2.??? ibatis 2.3.4

    3.??? spring 2.5

    4.??? eclipse 3.3

    完成賬戶的轉(zhuǎn)賬功能,在出現(xiàn)異常時(shí)回滾。由spring管理各個(gè)類之間的關(guān)系和事務(wù)處理。

    1. 首先建立兩個(gè)數(shù)據(jù)庫(kù),一個(gè)在本機(jī)上,一個(gè)在遠(yuǎn)端機(jī)上,腳本分別如下
      ?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

      在這里兩個(gè)數(shù)據(jù)庫(kù)是完全一樣的,是為了方便起見(jiàn)

    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. 建立業(yè)務(wù)層接口AccountService
      ?1package?com.aaron.atomikos.service;
      ?2import?com.aaron.atomikos.domain.Account;
      ?3public?interface?AccountService?{
      ?4????void?addAccount(Account?account);
      ?5????
      ?6????/**
      ?7?????*?轉(zhuǎn)賬
      ?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. 建立業(yè)務(wù)層接口實(shí)現(xiàn)類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????//?數(shù)據(jù)庫(kù)a的Dao類
      ?8????private?AccountDao?accountaDao;
      ?9????//?數(shù)據(jù)庫(kù)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????????//轉(zhuǎn)賬
      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????????//兩次更新之間如果跑出異常,則會(huì)回滾操作
      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,這里為了簡(jiǎn)單起見(jiàn),沒(méi)有使用接口,直接寫(xiě)了具體實(shí)現(xiàn)類
    ?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?????*?根據(jù)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?????*?根據(jù)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?????*?根據(jù)賬戶編號(hào)得到余額
    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}
  • 編寫(xiě)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>
    還要建立兩個(gè)ibatis的配置文件sql-map-config_A.xml和sql-map-config_B.xml,由于有兩個(gè)數(shù)據(jù)庫(kù),所以要建兩個(gè)。具體不列出。
  • 編寫(xiě)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????<!--?讀取數(shù)據(jù)庫(kù)連接配置文件?-->
    ?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????<!--?數(shù)據(jù)源A(使用com.atomikos.jdbc.AtomikosDataSourceBean作為數(shù)據(jù)源)?-->
    ?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????<!--?數(shù)據(jù)源B(使用com.atomikos.jdbc.SimpleDataSourceBean作為數(shù)據(jù)源)?-->
    ?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的事務(wù)管理器?-->
    ?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事務(wù)管理器?-->
    ?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????<!--?事務(wù)切面配置?-->
    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????<!--?根據(jù)dataSourceA和sql-map-config_A.xml創(chuàng)建一個(gè)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????<!--?根據(jù)dataSourceB和sql-map-config_B.xml創(chuàng)建一個(gè)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????<!--根據(jù)sqlMapClientA創(chuàng)建一個(gè)SqlMapClientTemplate的模版類實(shí)例sqlMapClientTemplateA-->
    131????<bean?id="sqlMapClientTemplateA"
    132????????class="org.springframework.orm.ibatis.SqlMapClientTemplate">
    133????????<property?name="sqlMapClient"?ref="sqlMapClientA"?/>
    134????</bean>
    135
    136????<!--根據(jù)sqlMapClientB創(chuàng)建一個(gè)SqlMapClientTemplate的模版類實(shí)例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>
    在這里,我使用了兩個(gè)不同類的數(shù)據(jù)源,只是為了測(cè)試,具體配置如上。兩者設(shè)置屬性時(shí)有點(diǎn)差別,數(shù)據(jù)源com.atomikos.jdbc.AtomikosDataSourceBean中設(shè)置url,user,password屬性是用xaProperties這個(gè)屬性,它是個(gè)Properties類型,所以要用<props>標(biāo)簽分開(kāi)設(shè)置,數(shù)據(jù)源com.atomikos.jdbc.SimpleDataSourceBean中設(shè)置url,user,password屬性使用xaDataSourceProperties這個(gè)屬性,它是String類型,查看源代碼可以知道,這個(gè)類會(huì)把xaDataSourceProperties按“;”進(jìn)行分割,得到user=root,password=root等幾個(gè)字符串,再將“=”兩邊的字符串分別作為屬性名和屬性值放入一個(gè)properties變量中。有一點(diǎn)要注意,
    1<value>user=${jdbc2.username};password=${jdbc2.password};url=${jdbc2.url};encoding=${jdbc2.encoding}</value>
    中的<value>和user=${jdbc2.username}之間不能換行,因?yàn)樵擃惒粫?huì)忽略換行,會(huì)把換行加上user當(dāng)成一個(gè)字符串,之后會(huì)報(bào)錯(cuò)的。
  • 編寫(xiě)測(cè)試類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}

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

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费女人高潮流视频在线观看 | 亚洲国产成人va在线观看网址| 乱人伦中文视频在线观看免费| 鲁死你资源站亚洲av| 久久免费看黄a级毛片| 午夜dj免费在线观看| 国产亚洲av片在线观看18女人| 亚洲日本香蕉视频观看视频| A级毛片高清免费视频在线播放| 成年轻人网站色免费看| 不卡精品国产_亚洲人成在线| 在线91精品亚洲网站精品成人| 99久久免费看国产精品| 亚洲成av人片天堂网| 9久热精品免费观看视频| 亚洲区不卡顿区在线观看| 亚洲美女视频一区| 三年片在线观看免费| 国产亚洲精品自在线观看| 特a级免费高清黄色片| 亚洲AV无码之日韩精品| 亚洲精品91在线| 日韩免费高清播放器| 亚洲国产精品无码久久久蜜芽 | 永久免费看bbb| 亚洲日产乱码一二三区别| 免费A级毛片无码免费视| 77777午夜亚洲| 妞干网免费视频在线观看| 亚洲va无码专区国产乱码| 久久水蜜桃亚洲AV无码精品| 日韩免费观看视频| 亚洲精品国产免费| 亚洲成人在线免费观看| 亚洲制服丝袜在线播放| 国产美女在线精品免费观看| 亚洲Av永久无码精品一区二区| 日韩精品视频免费观看| 国产91成人精品亚洲精品| 亚洲国产综合精品中文字幕| 国产99精品一区二区三区免费|