Spring配置式事物(基于xml)
文件目录结构
java类
public interface BookShopDao {
public int findBookPriceByIsbn(String isbn);
public void updateBookStock(String isbn);
public void updateUserAccount(String username, int price);
}
public class BookShopDaoImpl implements BookShopDao {
private JdbcTemplate jt;
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
public int findBookPriceByIsbn(String isbn) {
String sql = "SELECT price FROM book WHERE isbn=?";
return jt.queryForObject(sql, Integer.class, isbn);
}
public void updateBookStock(String isbn) {
// 检查书的库存是否足够,若不够,则抛出异常
String sql2 = "SELECT stock FROM book_stock WHERE isbn=?";
Integer stock = jt.queryForObject(sql2, Integer.class, isbn);
if (stock == 0) {
throw new BookStockException("库存不足!");
}
String sql = "UPDATE book_stock SET stock=stock-1 WHERE isbn=?";
int update = jt.update(sql, isbn);
System.out.println("更新了-->" + update + "条");
}
public void updateUserAccount(String username, int price) {
// 验证用户的余额是否足够
String banalce = "SELECT balance FROM account WHERE username=?";
int ba = jt.queryForObject(banalce, Integer.class, username);
if (ba > 0 && ba < price) {
throw new UserAccountException("账户余额不足!");
}
String sql = "UPDATE account SET balance=balance-? WHERE username=?";
int update = jt.update(sql, price, username);
System.out.println("更新了-->" + update + "条");
}
}
public class BookStockException extends RuntimeException {
...//实现方法
}
public class UserAccountException extends RuntimeException {
…//实现方法
}
public interface BookShopService {
public void purchase(String username, String isbn);
}
public interface Cashier {
public void checkout(String username, List<String> isbns);
}
public class BookShopServiceImpl implements BookShopService {
private BookShopDao bsd;
public void setBsd(BookShopDao bsd) {
this.bsd = bsd;
}
public void purchase(String username, String isbn) {
// 1获取书的单价
int price = bsd.findBookPriceByIsbn(isbn);
// 2更新数的库存
bsd.updateBookStock(isbn);
// 3更新用户的余额
bsd.updateUserAccount(username, price);
}
}
public class CashierImpl implements Cashier {
private BookShopService bookShopService;
public void setBookShopService(BookShopService bookShopService) {
this.bookShopService = bookShopService;
}
public void checkout(String username, List<String> isbns) {
for (String isbn : isbns) {
bookShopService.purchase(username, isbn);
}
}
}
xml(核心)
<context:component-scan base-package="com.spring.beans"></context:component-scan>
<!-- 导入配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
<!--配置Spring的JdbcTemplate工具类 -->
<!--此处需要注意的用的是哪个持久层框架,就选用他的数据库操作工具类。
例如 如果持久层框架是mybatis -->
<!--
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
</bean>
-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="bookShopDao" class="com.spring.beans.tx.xml.BookShopDaoImpl">
<property name="jt" ref="jdbcTemplate"></property>
</bean>
<bean id="bookShopService"
class="com.spring.beans.tx.xml.service.impl.BookShopServiceImpl">
<property name="bsd" ref="bookShopDao"></property>
</bean>
<bean id="cashier" class="com.spring.beans.tx.xml.service.impl.CashierImpl">
<property name="bookShopService" ref="bookShopService"></property>
</bean>
<!-- 1、配置事物 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2、配置事物属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 根据方法名指定事物属性 -->
<tx:method name="purchase" propagation="REQUIRES_NEW" />
<tx:method name="get" read-only="true" />
<tx:method name="find" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 3、配置事物切入点,以及把事物切入点和事物属性关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.spring.beans.tx.xml.service.*.*(..))"
id="pointCut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
</aop:config>
测试类
public class BookShopDaoImplTest {
private ApplicationContext ctx = null;
private BookShopService bookShopService = null;
private Cashier cashier = null;
{
ctx = new ClassPathXmlApplicationContext("applicationContext-xml.xml");
bookShopService = (BookShopService) ctx.getBean("bookShopService");
cashier = ctx.getBean(Cashier.class);
}
@Test
public void testcashier() {
cashier.checkout("AA", Arrays.asList("1001", "1002"));
}
@Test
public void testbookShopService() {
bookShopService.purchase("AA", "1001");
}
}