1. 程式人生 > >spring 事務管理的簡單配置

spring 事務管理的簡單配置

ger string oot code nal chan 價格 nts 每次

1:事務的優點

  事務管理對平時的業務邏輯的健壯性幫助很大,它保證了一個動作的原子性

  本例中主要體現在,購票或者購書中,業務邏輯如下:

    1:根據商品的ID查詢該商品的價格,

    2:根據商品的價格去扣除用戶的余額,但余額不足時,主動拋出異常

    3:當用戶付款成功後,扣除商品庫存,單庫存不足時,主動拋出異常

   當3個步驟都操作成功後,數據庫才會真正的持久化,即數據發生改變

  項目路徑保存在 D:\海同\spring\9.14\9.14

  額外jar包:

    aopalliance.jar 和 aspectjweaver.jar 和 spring-aspects-4.2.0.RELEASE.jar 切面必須包

    c3p0-0.9.2.1.jar 和 commons-logging-1.1.1.jar 和 mysql-connector-java-5.1.7-bin.jar 數據庫必須包

2:註解配置事務流程

    比較方便

  Repository層接口:

public interface GoodDao {
    //查找商品價格
    public int findPriceById(String id);

    //修改商品數量每次-1
    public void updateGoods(String id);

    //修改用戶的余額
    public void updateBalance(String username,int
price); }

  Repository層實體:

/聲明並裝配到spring容器中去
@Repository("goodDao")
public class GoodDaoImpl implements GoodDao {
//    配置屬性,從spring容器中取出 JdbcTemplate 對象
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Override
    public int findPriceById(String id) {
        String sql 
= "select price from goods where id = ?"; // 返回值為Integer的類類型 return jdbcTemplate.queryForObject(sql,Integer.class,id); } @Override public void updateGoods(String id) { String select = "SELECT NUMBER FROM good_numbers WHERE id = ?"; int number = jdbcTemplate.queryForObject(select,Integer.class,id); if (number < 1){
//      該異常為自定義異常,僅繼承了 RunTimeException 不貼上代碼
throw new GoodException("商品數量不足"); } String sql = "update good_numbers set number = number-1 where id = ?"; jdbcTemplate.update(sql,id); } @Override public void updateBalance(String username, int price) { String select = "SELECT balance FROM users WHERE username = ?"; int balance = jdbcTemplate.queryForObject(select,Integer.class,username); if (balance < price){
//      該異常為自定義異常,僅繼承了 RunTimeException 不貼上代碼
        throw new UserException("用戶余額不足"); } 
     String sql
= "update users set balance = balance - ? where username = ?";
     jdbcTemplate.update(sql,price,username);
}
}

  Service層的接口和實現:

  

//接口
public interface GoodService {
    public void buyGood(String username,String id);
}

//實現類
@Service("goodService")
public class GoodServiceImpl implements GoodService {
    @Resource(name = "goodDao")
    private GoodDao goodDao;

    @Transactional
    @Override
    public void buyGood(String username, String id) {
        int price = goodDao.findPriceById(id);
        goodDao.updateGoods(id);
        goodDao.updateBalance(username,price);
    }


}

   測試類

public class TestGoodService {
    private GoodService goodService;

    @Test
    public void test(){
        ApplicationContext applicationContext =new  ClassPathXmlApplicationContext("application.xml");
        this.goodService = (GoodService) applicationContext.getBean("goodService");
        goodService.buyGood("aa","1");
    }
}

  XML的配置方式:

  xml中僅僅是在配置文件中不同,和實體類中取出了所有的註解,故,只將xml文件帖出:

  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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       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-4.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--讀取配置文件-->
    <context:property-placeholder location="classpath:db.property"></context:property-placeholder>
    <!--加載數據源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
     </bean>
    <!--註入spring中的JdbcTemplate-->
    <bean  id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--註入repository-->
    <bean id="goodDao" class="com.yuwenhui.jdbc.xml.repository.GoodDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    <!--註入Service-->
    <bean id="goodService" class="com.yuwenhui.jdbc.xml.service.GoodServiceImpl">
        <property name="goodDao" ref="goodDao"></property>
    </bean>
    <!--配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置事務屬性-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置aop -->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.yuwenhui.jdbc.xml.service.GoodServiceImpl.* (..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" id="aopAdvisor"/>
    </aop:config>
</beans>

 

 配置文件 db.propertys

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring
jdbc.user=root
jdbc.password=123456

spring 事務管理的簡單配置