Spring中TransactionTemplate 简单灵活的事务配置及使用

7 篇文章 0 订阅

在一般的交易类程序中会频繁的使用事务来约束重要或关键的动作,已保证交易行为的整体性和一致性。

下例中是在Spring框架下中使用JDBC连接数据库的事务示例。

1.配置文件内容 

数据源、事务的底层配置

<?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:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
	http://www.springframework.org/schema/tx   
	http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
    <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
    	<property name="driver" value="oracle.jdbc.OracleDriver" />
		<property name="driverUrl" value="jdbc:oracle:thin:@127.0.0.1:1523:NTDATA" />
		<!-- property name="driverUrl" value="jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.31.1)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.31.2)(PORT = 1521))(LOAD_BALANCE = OFF)(FAILOVER=ON)(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = zfpay1)(FAILOVER_MODE=(TYPE = SELECT)(METHOD = BASIC)(RETIRES = 20)(DELAY = 15))))" /> -->
		<property name="user" value="jfb3" />
		<property name="password" value="jfb3" />
		<property name="alias" value="ecpay" />
		<property name="maximumActiveTime" value="300000" />
		<property name="prototypeCount" value="0" />
		<property name="maximumConnectionCount" value="50" />
		<property name="minimumConnectionCount" value="2" />
		<property name="simultaneousBuildThrottle" value="50" />
		<property name="houseKeepingTestSql" value="select 1 from dual" />
    </bean>
    
    <!-- jdbc事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
	</bean>
    <!--事务模板 -->
	<bean id="transactionTemplate"
		class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager">
			<ref local="transactionManager" />
		</property>
		<!--ISOLATION_DEFAULT 表示由使用的数据库决定  -->
		<property name="isolationLevelName" value="ISOLATION_DEFAULT"/>
		<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
  		<!-- <property name="timeout" value="30"/> -->
	</bean>
    <!-- 启动使用注解实现声明式事务管理的支持
    <tx:annotation-driven transaction-manager="txManager" /> -->
</beans>

DAO层的配置

	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	<bean id="sequence8" class="org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer">
		<property name="incrementerName" value="EPAY_SEQUENCE_8" />
		<property name="dataSource" ref="dataSource"/>
	</bean>
        <bean id="merchantMapDAO" class="cn.com.nantian.epayment.dao.MerchantMapDAO">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
	<bean id="payOrderDAO" class="cn.com.nantian.epayment.dao.PayOrderDAO">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
SERVICE层的配置

	<bean id="elecChnlFrontPayService"
		class="cn.com.nantian.epayment.pay.service.ElecChnlFrontPayServiceImpl">
		<property name="merchantMapDAO" ref="merchantMapDAO" />
		<property name="payOrderDAO" ref="payOrderDAO" />
		<property name="transactionTemplate" ref="transactionTemplate" />
	</bean>

程序示例代码

	
	private PayOrderDAO payOrderDAO;
	
	protected TransactionTemplate transactionTemplate;

	/**
	 * 保存支付订单
	 */
	protected PayOrder savePayReq(final PayOrder payOrder) {

		PayOrder order = (PayOrder) this.transactionTemplate
				.execute(new TransactionCallback() {
					@Override
					public Object doInTransaction(TransactionStatus status) {
						// 查看是否已经存在支付订单,如果已经存在则返回订单主键
						PayOrder payOrderTemp = payOrderDAO.findOrder(String
								.valueOf(payOrder.getPayOrderId()));

						// 由支付渠道类型(PayChannelType)转换得到交易类型(PayType)
						if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_ACT_BAL)) {// 账户余额支付
							payOrder.setPayType("3");
						} else if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_FAST_PAY)) {// 联通快捷支付
							payOrder.setPayType("4");
						} else {// 网银网关支付
							payOrder.setPayType("2");
						}

						// 比对新的支付金额与原订单金额是否一致,如不一致则提示错误
						if (payOrderTemp == null) {
							String orderId = payOrderDAO.save(payOrder);
							payOrder.setPayOrderId(orderId);
							return payOrder;
						} else {
							return payOrderTemp;
						}
					}
				});
		if ("2".equals(order.getOrderState())) {// 2:表示支付成功
			throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
					"同一订单不能重复支付");
		} else if (payOrder.getPayAmt().longValue() != order.getPayAmt()
				.longValue()) {
			throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
					"交易金额与原订单不一致");
		} else {
			return payOrder;
		}

	}

	public PayOrderDAO getPayOrderDAO() {
		return payOrderDAO;
	}

	public void setPayOrderDAO(PayOrderDAO payOrderDAO) {
		this.payOrderDAO = payOrderDAO;
	}

	public TransactionTemplate getTransactionTemplate() {
		return transactionTemplate;
	}

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}
程序中先查询数据库中是否已有相同的订单号以避免重复订单,查询没有相同的订单号后将传入参数入库。本例中将着两个过程设置在一个事务中。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值