【Spring4.0】基于Xml的方式进行事务管理

##一、前情提要

此文章时关于基于Xml的方式配置Spring事务管理,由于前面我已经出炉了一篇《【Spring4.0】Spring基于注解方式进行事务管理》,里面已经详细介绍了关于Aop的一些知识点,在这里我就不再详细介绍SpringAOP了,如有需要烦请翻阅我【Spring4.0】系列日志。



##二、前期准备工作

《【Spring4.0】Spring基于注解方式进行事务管理》一样导入相同的JAR包、同样的数据库数据即可。



##三、示例代码

![这里写图片描述](https://img-blog.csdn.net/20180807112318916?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNTk2OTc4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) ![这里写图片描述](https://img-blog.csdn.net/20180807111450131?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNTk2OTc4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
**(整个项目概览,只要创建xml包里面的文件即可)**

###(1)在src根目录配置外部连接数据库的属性文件db.properties

jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc\:mysql\://localhost\:3306/spring
jdbc.initPoolSize=5
jdbc.maxPoolSize=10

###(2)在com.spring.tx.xml.service创建相关的接口
BookShopDao

public interface BookShopDao {
	//根据书号获取书的单价
	public int findBookPriceByIsbn(String isbn);
	//更新数的库存. 使书号对应的库存 - 1
	public void updateBookStock(String isbn);
	//更新用户的账户余额: 使 username 的 balance - price
	public void updateUserAccount(String username, int price);
}

BookShopService

public interface BookShopService {
	public void purchase(String username, String isbn);
}

Cashier

public interface Cashier {
	public void checkout(String username, List<String> isbns);
}

###(3)在com.spring.tx.xml.service.impl创建相关的实现类
BookShopDao的实现类BookShopDaoImpl

package com.spring.tx.xml.service.impl;

import org.springframework.jdbc.core.JdbcTemplate;

import com.spring.tx.xml.BookStockException;
import com.spring.tx.xml.UserAccountException;
import com.spring.tx.xml.service.BookShopDao;

public class BookShopDaoImpl implements BookShopDao {

	private JdbcTemplate jdbcTemplate;
	
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	@Override
	public int findBookPriceByIsbn(String isbn) {
		String sql = "SELECT price FROM book WHERE isbn = ?";
		return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
	}

	@Override
	public void updateBookStock(String isbn) {
		// 检查书的库存是否足够,若不够则抛出异常
		String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";
		int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
		if(stock == 0){
			throw new BookStockException("书本库存不足");
		}
		
		String sql = "UPDATE book_stock SET stock = stock - 1 WHERE isbn = ?";
		jdbcTemplate.update(sql, isbn);
	}

	@Override
	public void updateUserAccount(String username, int price) {
		String sql2 = "SELECT balance FROM account WHERE username = ?";
		int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);
		if(balance < price){
			throw new UserAccountException("余额不足");
		}
		String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";
		jdbcTemplate.update(sql, price, username);
	}

}

BookShopService的实现类BookShopServiceImpl

package com.spring.tx.xml.service.impl;

import com.spring.tx.xml.service.BookShopDao;
import com.spring.tx.xml.service.BookShopService;

public class BookShopServiceImpl implements BookShopService {

	private BookShopDao bookShopDao;

	public void setBookShopDao(BookShopDao bookShopDao) {
		this.bookShopDao = bookShopDao;
	}

	public void purchase(String username, String isbn) {
		// 1.获取书的单价
		int price = bookShopDao.findBookPriceByIsbn(isbn);
		// 2.更新数据库库存
		bookShopDao.updateBookStock(isbn);
		// 3.更新用户价格
		bookShopDao.updateUserAccount(username, price);
	}

}

Cashier的实现类CashierImpl

package com.spring.tx.xml.service.impl;

import java.util.List;

import org.springframework.stereotype.Service;

import com.spring.tx.xml.service.BookShopService;
import com.spring.tx.xml.service.Cashier;

@Service("cashier")
public class CashierImpl implements Cashier {

	private BookShopService bookShopService;

	public void setBookShopService(BookShopService bookShopService) {
		this.bookShopService = bookShopService;
	}

	@Override
	public void checkout(String username, List<String> isbns) {
		for (String isbn : isbns) {
			bookShopService.purchase(username, isbn);
		}
	}

}

###(4)在com.spring.tx.xml创建异常类
库存不足的异常类BookStockException

package com.spring.tx.xml;

public class BookStockException extends RuntimeException {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8345575141732656052L;

	public BookStockException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	

}

代表用户余额不足的异常类UserAccountException

package com.spring.tx;

public class UserAccountException extends RuntimeException{

	/**
	 * 
	 */
	private static final long serialVersionUID = 3217299177229543901L;

	public UserAccountException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message, Throwable cause, boolean enableSuppression,
			boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	

}

###(5)配置xml文件applicationContext-tx-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:p="http://www.springframework.org/schema/p"
	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-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">


	<!-- 导入外部资源文件 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 配置C3P0数据源 -->
	<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="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>

	<!-- 配置Spring 的JdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 配置bean -->
	<bean id="bookShopDao" class="com.spring.tx.xml.service.impl.BookShopDaoImpl">
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>

	<bean id="bookShopService" class="com.spring.tx.xml.service.impl.BookShopServiceImpl">
		<property name="bookShopDao" ref="bookShopDao"></property>
	</bean>

	<bean id="cashier" class="com.spring.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:method name="*" />
		</tx:attributes>
	</tx:advice>

	<!-- 3.配置事务切入点,以及把事务切入点和事务关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.spring.tx.xml.service.*.*(..))"
			id="txPointCut" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
	</aop:config>
</beans>

猜你喜欢

转载自blog.csdn.net/qq_33596978/article/details/81478440