spring管理事物

  1. spring最普通的管理事物

    1.在applicationContext.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.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 內置的連接池:先配置連接池 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    -->


    <!-- 配置DBCP的連接池
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day03"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
     -->

    <!-- 配置C3P0的連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///mybatis"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!-- 配置JDBC的模板類 -->
    <!-- 配置平臺事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 聲明式事務(採用XML配置文件的方式) -->
    <!-- 先配置通知 -->
    <tx:advice id="myAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 給方法設置數據庫屬性(隔離級別,傳播行爲) -->
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置AOP:如果是自己編寫的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知aop:advisor -->
    <aop:config>
        <!-- aop:advisor,是Spring框架提供的通知  (..) 表示有參數  -->
        <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.tx.server.TxServeriImpl.transfer(..))"/>
    </aop:config>



    <!-- 開啓註解的掃描  
    <context:component-scan base-package="com.tx"/>
        -->
    <bean id="txserver" class="com.tx.server.TxServeriImpl">
        <property name="accountdao" ref="accountdao"/>
    </bean>

    <bean id="accountdao" class="com.tx.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

<!--  這個事物是沒有註解的,最原始的 -->
<!-- 
    事物其實就是,兩條sql執行,如果一條出現了問題,另外一條就進行回滾
    比如轉錢:
    小明 扣了一元
    小花就加一元
    可是在小明釦了錢以後出現了錯誤,
    小明的數據就必須要回滾,不然數據就會錯誤
 -->
2.dao層的java代碼
package com.tx.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import com.tx.bean.PayBean;

/**
 *  extends JdbcDaoSupport  
 *  使用裏面的jdbc自帶的增刪改查的方法
 * @author lenovo
 *
 */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{


    /**
     *  進錢
     */
    @Override
    public void inMonery(String name, double monery) {
        // TODO Auto-generated method stub

        this.getJdbcTemplate().update("UPDATE pay a set a.money = money + ? WHERE a.name = ?",monery,name);
    }

    /**
     * 扣錢
     * @param otherName 誰
     * @param monery 錢
     */
    @Override
    public void onMonery(String otherName, double monery) {
        // TODO Auto-generated method stub
        this.getJdbcTemplate().update("UPDATE pay a set a.money = money - ? WHERE a.name = ?",monery,otherName);
    }

    @Override
    public void selectAll() {
        // TODO Auto-generated method stub
        List<PayBean> queryForList = this.getJdbcTemplate().query("SELECT * from pay", new TestRowMap());
        for (PayBean payBean : queryForList) {
            System.out.println(payBean.getName());
        }
    }

    /**
     * 回調方法,其實是給查詢方法賦值
     * @author lenovo
     *
     */
    class TestRowMap implements RowMapper<PayBean>{

        @Override
        public PayBean mapRow(ResultSet resultSet, int arg1) throws SQLException {
            PayBean payBean = new PayBean();
            payBean.setName(resultSet.getString("name"));
            payBean.setMoney(resultSet.getDouble("money"));
            payBean.setAddname(resultSet.getString("addname"));
            return payBean;
        }

    }
}
3.server層中使用的方法
package com.tx.server;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;

import com.jdbc.bean.UserBean;
import com.tx.bean.PayBean;
import com.tx.dao.AccountDao;

public class TxServeriImpl implements TxServer {

    private Logger log = Logger.getLogger("log");

    //accountdao 必須和xml中配置的id 同名
    public AccountDao accountdao;
    public void setAccountdao(AccountDao accountdao) {
        this.accountdao = accountdao;
    }

    /**
     * 轉賬, 
     * @param name 轉賬主人
     * @param monery 多少錢
     * @param otherName 給誰
     */
    @Override
    public void transfer(String name, double monery, String otherName) {
        // TODO Auto-generated method stub

        accountdao.inMonery(name, monery);
        //int a = 100 / 0 ;
        //log.info(a+"");
        accountdao.onMonery(otherName, monery);
    }
}
4.test測試代碼
package com.tx.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.tx.server.TxServer;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class PayTest {

    @Resource(name = "txserver")
    public TxServer txServer;

    @Test
    public void run(){

        /**
         * 小明給小花 30.2元
         */
        txServer.transfer("小明", 1, "小花");
    }
}
  1. spring 使用註解的方法管理事物
    1.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.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 內置的連接池:先配置連接池 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    -->


    <!-- 配置DBCP的連接池
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day03"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
     -->

    <!-- 配置C3P0的連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///mybatis"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!-- 配置JDBC的模板類 -->
    <!-- 配置平臺事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 開啓註解的掃描  -->
    <context:component-scan base-package="com.tx2"/>
    <!-- 開啓自動代理 aop代理掃描-->
    <aop:aspectj-autoproxy/>
    <!-- 開啓事務的註解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="txserver" class="com.tx2.TxServeriImpl">
        <property name="accountdao" ref="accountdao"/>
    </bean>

    <bean id="accountdao" class="com.tx2.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

<!--  

這個事物是有註解的,最原始的 -->
<!-- 
    註解的方法
    事物其實就是,兩條sql執行,如果一條出現了問題,另外一條就進行回滾
    比如轉錢:
    小明 扣了一元
    小花就加一元
    可是在小明釦了錢以後出現了錯誤,
    小明的數據就必須要回滾,不然數據就會錯誤
 -->
2.dao層和上面的1.2一樣
3.serverc層代碼
package com.tx2;

import java.util.logging.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * 在類上面添加,所有的方法都有事物管理
 * @author lenovo
 *
 */
@Transactional
public class TxServeriImpl implements TxServer {


    public void setAccountdao(AccountDao accountdao) {
        this.accountdao = accountdao;
    }

    @Autowired
    public AccountDao accountdao;

    /**
     * 轉賬, 
     * @param name 轉賬主人
     * @param monery 多少錢
     * @param otherName 給誰
     */
    @Override
    public void transfer(String name, double monery, String otherName) {
        // TODO Auto-generated method stub

        accountdao.inMonery(name, monery);
        int a = 100 / 0 ;
        //log.info(a+"");
        accountdao.onMonery(otherName, monery);
    }

    @Override
    public void selectAll() {
        // TODO Auto-generated method stub
        accountdao.selectAll();
    }


}
4.test測試
package com.tx2;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class PayTest {

    @Resource(name = "txserver")
    public TxServer txServer;

    @Test
    public void run(){

        /**
         * 小明給小花 30.2元
         */
        txServer.transfer("小明", 1, "小花");
        //txServer.selectAll();
    }
}

3.代碼demo地址 https://gitee.com/yuhaifei/springJDBC.git
3.1 spring普通方法com.tx包下
3.2 spring注入的方法在com.tx2包下
3.3 com/Spring_day03.md 是黑馬老師的筆記,非常感謝老師

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章