本地事务系列之三:使用TransactionTemplate

TransactionTemplate的灵活性好,可以给代码块加事务处理,而不是方法粒度的控制。

FruitShop实现:
public class TxTemplateJdbcFruitShop extends JdbcDaoSupport implements FruitShop {
	private PlatformTransactionManager txManager;

	public void setTxManager(PlatformTransactionManager txManager) {
		this.txManager = txManager;
	}

	@Override
	public boolean purchase(final int fruitId, final String userName, final int count) {
		TransactionTemplate txTemplate = new TransactionTemplate(txManager);
		
		final String querySql = "SELECT PRICE FROM FRUIT WHERE ID = ?";
		final String upStockSql = "UPDATE FRUIT_STOCK SET STOCK = STOCK - ? WHERE ID = ?";
		final String upAccountSql = "UPDATE ACCOUNT SET BALANCE = BALANCE - ? WHERE USERNAME = ?";

		int retVal = txTemplate.execute(new TransactionCallback<Integer>() {

			@Override
			public Integer doInTransaction(TransactionStatus status) {
				int price = getJdbcTemplate().queryForInt(querySql, new Object[] { fruitId });
				getJdbcTemplate().update(upStockSql, new Object[] { count, fruitId });
				getJdbcTemplate().update(upAccountSql, new Object[] { price * count, userName });
				return 1;
			}
		});

		return retVal == 1;
	}
}


beans-fruitshop.xml文件加入:
<bean id="txTemplateFruitShop" class="com.john.tx.service.impl.TxTemplateJdbcFruitShop">
  <property name="dataSource" ref="dataSource" />
  <property name="txManager" ref="txManager" />
</bean>


JdbcFruitShopTest类加入:
@Resource(name = "txTemplateFruitShop")
FruitShop txTemplateFruitShop;

@Test
public void txTemplateTest() {
	int fruitId = 1;
	String userName = "user1";
	int count = 3;
	txTemplateFruitShop.purchase(fruitId, userName, count);
}



附:
1. 可以直接注入TransactionTemplate实例,不用在代码中实例化:
去除PlatformTransactionManager属性,直接使用TransactionTemplate属性:
private TransactionTemplate txTemplate;

public void setTxTemplate(TransactionTemplate txTemplate) {
	this.txTemplate = txTemplate;
}


beans-fruitshop.xml加入:
<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
  <property name="transactionManager" ref="txManager" />
</bean>

<bean id="txTemplateFruitShop" class="com.john.tx.service.impl.TxTemplateJdbcFruitShop">
  <property name="dataSource" ref="dataSource" />
  <property name="txTemplate" ref="txTemplate" />
</bean>


2. execute方法可以接受TransactionCallback接口的抽象类,如TransactionCallbackWithoutResult:
txTemplate.execute(new TransactionCallbackWithoutResult() {

	@Override
	protected void doInTransactionWithoutResult(TransactionStatus status) {
		...
	}
});


看下其实现:
接口方法中抽出一个没有返回结果的抽象方法(由用户自己实现),返回null是为了适配接口。
public abstract class TransactionCallbackWithoutResult implements TransactionCallback<Object> {
	public final Object doInTransaction(TransactionStatus status) {
		doInTransactionWithoutResult(status);
		return null; // 返回null
	}

	// 抽象方法,需要自定义实现
	protected abstract void doInTransactionWithoutResult(TransactionStatus status);
}

你可能感兴趣的:(spring,manager,template,transaction)