Spring事务 注解模式(购物等例子适用)

  自从有了基于aop的事务注解,事务的使用变得更简单,相信大家都喜欢这货。够轻、够好用,哪里需要事务只需要一个注解即可,可以在类或者是方法上使用它。

流程如下:
①查询上平(通过id)得到上平的价格
②选择商品(通过id)将商品数量减一
③用户余额修改(用户名)余额减去商品的价格
要注意的是,用户余额不足的时候不能购买商品,商品数量不足的时候用户也不能购买商品
 
程序需要的jar包:

  aopalliance.jar
  aspectjweaver.jar
  c3p0-0.9.2.1.jar
  commons-codec-1.10.jar
  commons-logging.jar
  mchange-commons-java-0.2.3.4.jar
  mysql-connector-java-5.1.7-bin.jar
  spring-aop-4.2.0.RELEASE.jar
  spring-aspects-4.2.0.RELEASE.jar
  spring-beans-4.2.0.RELEASE.jar
  spring-context-4.2.0.RELEASE.jar
  spring-core-4.2.0.RELEASE.jar
  spring-expression-4.2.0.RELEASE.jar
  spring-jdbc-4.2.0.RELEASE.jar
  spring-tx-4.2.0.RELEASE.jar、

GoodDao.java

package com.qb.spring.tx;

public interface GoodDao {
    //查找商品价格
    public int findPriceById(String id);
    
    //修改商品数量每次-1
    public void updateGoods(String id);
    
    //修改用户的余额
    public void updateBalance(String username,int price);
}

GoodDaoImpl.java

package com.qb.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.qb.spring.tx.GoodsException;
import com.qb.spring.tx.UserException;
//声明并配置到Spring中 @Repository(
"goodDao") public class GoodDaoImpl implements GoodDao {
//配置属性自动 @Autowired
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 sql2 = "select number from good_numbers where id = ?"; int number = jdbcTemplate.queryForObject(sql2, Integer.class, id); if(number<0){
//      该异常为自定义异常,仅继承了 RunTimeException
throw new GoodsException("商品数量不足"); } String sql="update good_numbers set number=number-1 where id=?"; jdbcTemplate.update(sql, id); } @Override public void updateBalance(String username, int price) { String sql2 = "select balance from users where username=?"; int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username); if(balance-price<0){ throw new UserException("用户余额不足"); } String sql = "update users set balance=balance-? where username=?"; jdbcTemplate.update(sql, price,username); } }

GoodService.java

package com.qb.spring.tx;

public interface GoodService {
    public void buyGoods(String username,String id);
}

GoodServiceImpl.java

package com.qb.spring.tx;

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


@Service("goodService")
public class GoodServiceImpl implements GoodService {
    @Autowired
    private GoodDao goodDao;
    @Transactional
    @Override
    public void buyGoods(String username,String id) {
        int price = goodDao.findPriceById(id);
        goodDao.updateGoods(id);
        goodDao.updateBalance(username, price);

    }

}

GoodException.java

package com.qb.spring.tx;

public class GoodsException extends RuntimeException{

    public GoodsException() {
        super();
    }

    public GoodsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public GoodsException(String message, Throwable cause) {
        super(message, cause);
    }

    public GoodsException(String message) {
        super(message);
    }

    public GoodsException(Throwable cause) {
        super(cause);
    }
    
}

UserException.java

package com.qb.spring.tx;

public class UserException extends RuntimeException{

    public UserException() {
        super();
    }

    public UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public UserException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserException(String message) {
        super(message);
    }

    public UserException(Throwable cause) {
        super(cause);
    }

}

Test.java

package com.qb.spring.tx;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        GoodService goodService = (GoodService)applicationContext.getBean("goodService");
        goodService.buyGoods("aa", "1");
    }
}
application.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" 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">
  <!-- 扫描注解-->
<context:component-scan base-package="com.qb.spring.tx"></context:component-scan>    <!-- 加入配置文件db.properties -->
<context:property-placeholder location="classpath:db.properties" />
    <!-- 配置数据源 -->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> </bean>

  <!-- 配置 Spring的NamedParamterJdbcTemplate 只能构造器注入dataSource -->
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置事务管理器 -->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 启用事务的注解 -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
        
</beans>

db.propertice

driverClass=com.mysql.jdbc.Driver//数据库驱动
jdbcUrl=jdbc:mysql:///0912 //数据库路径
user=root //数据库用户名
password=123456 //数据库密码

数据库代码:

create table goods(
    id varchar(50) primary key,
    good_name varchar(100),
    price int
);

create table good_numbers(
    id varchar(50) primary key,
    number int,
    check(number > 0)
);

create table users(
    username varchar(50) primary key,
    balance int, 
    check(balance >0)
);


insert into goods(id,good_name,price) values('1','java',250);
insert into goods(id,good_name,price) values('2','javaweb',125);

insert into good_numbers(id,number) values('1',10);
insert into good_numbers(id,number) values('2',10);

insert into users(username,balance) values('aa',1000);
insert into users(username,balance) values('bb',1000);

 
原文地址:https://www.cnblogs.com/qiubin/p/7522535.html