需要的jar包:
c3p0-0.9.2.1.jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
mchange-commons-java-0.2.3.4.jar
mysql-connector-java-5.0.8-bin.jar
spring-aop-4.2.2.RELEASE.jar
spring-beans-4.2.2.RELEASE.jar
spring-context-4.2.2.RELEASE.jar
spring-core-4.2.2.RELEASE.jar
spring-expression-4.2.2.RELEASE.jar
spring-jdbc-4.2.2.RELEASE.jar
spring-tx-4.2.2.RELEASE.jar
1.注解方式的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:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context.xsd 10 http://www.springframework.org/schema/tx 11 http://www.springframework.org/schema/tx/spring-tx.xsd"> 12 13 <!-- 包扫描 --> 14 <context:component-scan base-package="com.eduask.liusheng"/> 15 16 <!-- 引入属性文件 --> 17 <context:property-placeholder location="db.properties"/> 18 19 <!-- 配置数据源 --> 20 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 21 <property name="driverClass" value="${jdbc.driver}"></property> 22 <property name="jdbcUrl" value="${jdbc.url}"></property> 23 <property name="user" value="${jdbc.username}"></property> 24 <property name="password" value="${jdbc.password}"></property> 25 </bean> 26 27 <!-- 配置jdbcTemplate模版 --> 28 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 29 <property name="dataSource" ref="dataSource"></property> 30 </bean> 31 32 <!-- 配置事务管理器 --> 33 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 34 <property name="dataSource" ref="dataSource"></property> 35 </bean> 36 37 <!-- 开启事务管理驱动 --> 38 <tx:annotation-driven transaction-manager="transactionManager"/> 39 </beans>
1 public interface BookShopDao { 2 /** 3 * 根据isbn查找单价 4 * @param isbn 编号 5 * @return 6 */ 7 public int findBookPriceByIsbn(String isbn); 8 9 /** 10 * 修改库存 11 * @param isbn 编号 12 */ 13 public void updateBookStock(String isbn); 14 15 /** 16 * 修改账户余额 17 * @param username 用户名 18 * @param price 价格 19 */ 20 public void updateAccount(String username,int price); 21 22 }
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.jdbc.core.JdbcTemplate; 3 import org.springframework.stereotype.Repository; 4 5 @Repository("bookShopDao") 6 public class BookShopDaoImp implements BookShopDao { 7 @Autowired 8 private JdbcTemplate jdbcTemplate; 9 10 public int findBookPriceByIsbn(String isbn) { 11 String sql="select price from book where isbn=?"; 12 int price=jdbcTemplate.queryForObject(sql, Integer.class, isbn); 13 return price; 14 } 15 16 public void updateBookStock(String isbn) { 17 String sql="select stock from book_stock where isbn=?"; 18 int stock=jdbcTemplate.queryForObject(sql, Integer.class, isbn); 19 if (stock>0) { 20 sql="update book_stock set stock=stock-1 where isbn=?"; 21 jdbcTemplate.update(sql, isbn); 22 } else { 23 throw new RuntimeException("库存不足!"); 24 } 25 } 26 27 @Override 28 public void updateAccount(String username, int price) { 29 String sql="select balance from account where username=?"; 30 int balance=jdbcTemplate.queryForObject(sql, Integer.class, username); 31 if (balance>=price) { 32 sql="update account set balance=balance-? where username=?"; 33 jdbcTemplate.update(sql, price,username); 34 } else { 35 throw new RuntimeException("余额不足!"); 36 } 37 } 38 39 }
1 public interface BookShopService { 2 /** 3 * 购买功能 4 * @param username 用户名 5 * @param isbn 书编号 6 */ 7 public void purchase(String username,String isbn); 8 }
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.stereotype.Service; 3 import org.springframework.transaction.annotation.Isolation; 4 import org.springframework.transaction.annotation.Propagation; 5 import org.springframework.transaction.annotation.Transactional; 6 7 import com.eduask.liusheng.dao.BookShopDao; 8 @Service("bookShopService") 9 public class BookShopServiceImp implements BookShopService { 10 @Autowired 11 private BookShopDao bookShopDao; 12 13 @Transactional(propagation=Propagation.REQUIRES_NEW,timeout=3) 14 public void purchase(String username, String isbn) { 15 16 //1.根据编号查询价格 17 int price=bookShopDao.findBookPriceByIsbn(isbn); 18 19 //2.修改库存 20 bookShopDao.updateBookStock(isbn); 21 //测试超时 22 // try { 23 // Thread.sleep(8000); 24 // } catch (InterruptedException e) { 25 // // TODO Auto-generated catch block 26 // e.printStackTrace(); 27 // } 28 29 //3.修改余额 30 bookShopDao.updateAccount(username, price); 31 32 } 33 34 }
1 import java.util.List; 2 3 public interface BookShopCashier { 4 /** 5 * 结账 6 * @param isbns 7 * @param username 8 */ 9 public void checkOut(List<String> isbns,String username); 10 }
1 import java.util.List; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Service; 5 import org.springframework.transaction.annotation.Transactional; 6 @Service("bookShopCashier") 7 public class BookShopCashierImp implements BookShopCashier { 8 @Autowired 9 private BookShopService bookShopService; 10 11 @Transactional 12 public void checkOut(List<String> isbns, String username){ 13 for (String isbn : isbns) { 14 bookShopService.purchase(username, isbn); 15 } 16 } 17 18 }
@Transactional(属性)
传播行为propagation 常用REQUIRES_NEW与REQUIRED
隔离事务isolation 默认READ_COMMITTED 拓展并发事务引起的问题,脏读.不可重复度,幻读
rollbackFor 和noRollbackFor 设置回滚与不回滚 默认RunTimeException自动回滚,checked的异常不回滚
timeout 设置超时时间,单位s
2.xml方式的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:context="http://www.springframework.org/schema/context" 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 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/tx 12 http://www.springframework.org/schema/tx/spring-tx.xsd 13 http://www.springframework.org/schema/aop 14 http://www.springframework.org/schema/aop/spring-aop.xsd"> 15 16 <bean id="bookShopDao" class="com.eduask.liusheng.dao.BookShopDaoImp" autowire="byName"/> 17 18 <bean id="bookShopService" class="com.eduask.liusheng.service.BookShopServiceImp" autowire="byName"/> 19 20 <bean id="bookShopCashier" class="com.eduask.liusheng.service.BookShopCashierImp" autowire="byName"/> 21 22 <!-- 引入属性文件 --> 23 <context:property-placeholder location="db.properties"/> 24 25 <!-- 配置数据源 --> 26 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 27 <property name="driverClass" value="${jdbc.driver}"></property> 28 <property name="jdbcUrl" value="${jdbc.url}"></property> 29 <property name="user" value="${jdbc.username}"></property> 30 <property name="password" value="${jdbc.password}"></property> 31 </bean> 32 33 <!-- 配置jdbcTemplate模版 --> 34 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 35 <property name="dataSource" ref="dataSource"></property> 36 </bean> 37 38 <!-- 配置事务管理器 --> 39 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 40 <property name="dataSource" ref="dataSource"></property> 41 </bean> 42 43 <!-- 配置事务通知 --> 44 <tx:advice id="advice" transaction-manager="transactionManager"> 45 <!-- 46 name 方法名 47 propagation 传播属性:REQUIRES_NEW,REQUIRED 事务被挂起的时间不计入超时时间 48 isolation 隔离事务级别 MySQL4种,Oracle2种 49 timeout 超时时间 :-1永不超时,单位s;防止长期运行的事务占用资源 50 no-rollback-for 不回滚 (异常名) 51 rollback-for 回滚 52 任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚 53 read-only 只读属性:表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务 54 --> 55 <tx:attributes> 56 <tx:method name="purchase" propagation="REQUIRED" isolation="READ_COMMITTED" /> 57 <tx:method name="checkOut" propagation="REQUIRED" isolation="READ_COMMITTED" timeout="3"/> 58 <!-- 增删改方法 --> 59 <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> 60 <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> 61 <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> 62 <!-- 查询方法只读 --> 63 <tx:method name="*" read-only="true"/> 64 </tx:attributes> 65 </tx:advice> 66 67 <!-- 配置切点 --> 68 <aop:config> 69 <!-- 配置切点 --> 70 <aop:pointcut expression="execution(* com.eduask.liusheng.service.*.*(..))" id="pointcut"/> 71 <!-- 关联切点与通知 --> 72 <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/> 73 </aop:config> 74 75 </beans>
1 import org.springframework.jdbc.core.JdbcTemplate; 2 3 public class BookShopDaoImp implements BookShopDao { 4 5 private JdbcTemplate jdbcTemplate; 6 7 public JdbcTemplate getJdbcTemplate() { 8 return jdbcTemplate; 9 } 10 11 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 12 this.jdbcTemplate = jdbcTemplate; 13 } 14 15 public int findBookPriceByIsbn(String isbn) { 16 String sql="select price from book where isbn=?"; 17 int price=jdbcTemplate.queryForObject(sql, Integer.class, isbn); 18 return price; 19 } 20 21 public void updateBookStock(String isbn) { 22 String sql="select stock from book_stock where isbn=?"; 23 int stock=jdbcTemplate.queryForObject(sql, Integer.class, isbn); 24 if (stock>0) { 25 sql="update book_stock set stock=stock-1 where isbn=?"; 26 jdbcTemplate.update(sql, isbn); 27 } else { 28 throw new RuntimeException("库存不足!"); 29 } 30 } 31 32 33 public void updateAccount(String username, int price) { 34 String sql="select balance from account where username=?"; 35 int balance=jdbcTemplate.queryForObject(sql, Integer.class, username); 36 if (balance>=price) { 37 sql="update account set balance=balance-? where username=?"; 38 jdbcTemplate.update(sql, price,username); 39 } else { 40 throw new RuntimeException("余额不足!"); 41 } 42 } 43 44 }
1 import com.eduask.liusheng.dao.BookShopDao; 2 3 public class BookShopServiceImp implements BookShopService { 4 5 private BookShopDao bookShopDao; 6 7 public BookShopDao getBookShopDao() { 8 return bookShopDao; 9 } 10 11 public void setBookShopDao(BookShopDao bookShopDao) { 12 this.bookShopDao = bookShopDao; 13 } 14 15 public void purchase(String username, String isbn) { 16 17 //1.根据编号查询价格 18 int price=bookShopDao.findBookPriceByIsbn(isbn); 19 20 //2.修改库存 21 bookShopDao.updateBookStock(isbn); 22 23 try { 24 Thread.sleep(8000); 25 } catch (InterruptedException e) { 26 // TODO Auto-generated catch block 27 e.printStackTrace(); 28 } 29 30 //3.修改余额 31 bookShopDao.updateAccount(username, price); 32 33 } 34 35 }
1 import java.util.List; 2 3 public class BookShopCashierImp implements BookShopCashier { 4 5 private BookShopService bookShopService; 6 7 public BookShopService getBookShopService() { 8 return bookShopService; 9 } 10 11 public void setBookShopService(BookShopService bookShopService) { 12 this.bookShopService = bookShopService; 13 } 14 15 public void checkOut(List<String> isbns, String username){ 16 for (String isbn : isbns) { 17 bookShopService.purchase(username, isbn); 18 } 19 } 20 21 }