Spring4_11_Spring对事务的支持(1)

事务:百度百科-事务

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

下面通过模拟银行转账来说明事务,以及Spring对事务的支持。


编程性事务管理

Spring提供事务模板类:TranscationTemplate

事务管理器:DataSourceTranscationManager

模拟银行转账

新建数据库  db_bank

 

表结构:

 

新建BankDao 接口

public interface BankDao {

	public void inMoney(int money,int userId);
	
	public void outMoney(int money,int userId);
}

 BankDaoImpl实现类:

public class BankDaoImpl implements BankDao{

	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	
	public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate     
                                          namedParameterJdbcTemplate) {
		this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
	}
	
	@Override
	public void inMoney(int money, int userId) {
		String sql = "update t_count set count=count+:money where userId=:userId";
		MapSqlParameterSource psp = new MapSqlParameterSource();
		psp.addValue("money", money);
		psp.addValue("userId", userId);
		namedParameterJdbcTemplate.update(sql, psp);
	}

	@Override
	public void outMoney(int money, int userId) {
		String sql = "update t_count set count=count-:money where userId=:userId";
		MapSqlParameterSource psp = new MapSqlParameterSource();
		psp.addValue("money", money);
		psp.addValue("userId", userId);
		namedParameterJdbcTemplate.update(sql, psp);
	}

}

service接口:

public interface BankService {

	/**
	 * A向B转账 count(元)
	 * @param count
	 * @param userIdA
	 * @param userIdB
	 */
	public void transferAccounts(int count,int userIdA,int userIdB);
	
}

serviceImpl:

public class BankServiceImpl implements BankService{

	private BankDao bankDao;
	
	public void setBankDao(BankDao bankDao) {
		this.bankDao = bankDao;
	}

	@Override
	public void transferAccounts(int count, int userIdA, int userIdB) {
		bankDao.outMoney(count, userIdA);
		bankDao.inMoney(count, userIdB);
	}

}

beans.xml:

	<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource"></constructor-arg>
	</bean>
	
	<bean id="bankDao" class="com.java.dao.impl.BankDaoImpl">
		<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
	</bean>
	
	<bean id="bankService" class="com.java.service.impl.BankServiceImpl">
		<property name="bankDao" ref="bankDao"></property>
	</bean>

现在测试:1给2转账50(元)

@Test
	public void test1() {
		BankService bankService = (BankService)ac.getBean("bankService");
		bankService.transferAccounts(50, 1, 2);
	}

当突发情况发生时:模拟异常:故意把inMoney里面的sql语句的表写错。

恢复原始数据再执行后发现:

 

讲道理说:如果出现异常,count应该回滚。

 Sping提供了一种编程性事务管理的策略:

注入transactionTemplate

	private TransactionTemplate transactionTemplate;
	
	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

把业务代码放进一个事务里:

	@Override
	public void transferAccounts(int count, int userIdA, int userIdB) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				
				bankDao.outMoney(count, userIdA);
				bankDao.inMoney(count, userIdB);
			}
		});
	}
}

beans.xml:jdbc事务管理器:

<!-- jdbc事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

事务模板:

<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
	</bean>

在service中注入transcationTemplate:

<property name="transactionTemplate" ref="transactionTemplate"></property>

恢复原始数据,再执行有异常的程序:

发现:发生异常会回滚。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值