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