好多东西网上都有,事务的特点就不说了, 直接来个简单的列子比较好.
spring中事务有两种实现方式, 一种是编程式事务, 一种是声明式事务
我个人来说喜欢用编程式事务, 总感觉明了一些, 可能只是习惯吧
新建一个springDemo项目
dao
public interface AccountDao {
/**
* 汇款
* @param outer 汇款人
* @param money 汇款金额
*/
public void out(String outer,int money);
/**
* 收款
* @param inner 收款人
* @param money 收款金额
*/
public void in(String inner,int money);
}
dao实现类
package dao.impl;
import dao.AccountDao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
/**
* 根据用户名减少账户金额
*/
public void out(String outer, int money) {
this.getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer);
}
/**
* 根据用户名增加账户金额
*/
public void in(String inner, int money) {
this.getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner);
}
}
service
package service;
public interface AccountService {
/**
* 转账
* @param outer 汇款人
* @param inner 收款人
* @param money 交易金额
*/
public void transfer(String outer,String inner,int money);
}
service是实现类
package service.impl;
import dao.AccountDao;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import service.AccountService;
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
private TransactionTemplate transactionTemplate;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void transfer(final String outer, final String inner, final int money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
accountDao.out(outer, money);
//int i = 1/0;
accountDao.in(inner, money);
}
});
}
}
在代码中需要用到TransactionTemplate模版, TransactionTemplate需要在xml中进行配置, 否则是不行的, 至于为什么需要配置 , 大家都是干这个的,应该能想到
在resources新建一个applicationContextTranscation.xml
事务模版和数据源管理器都有自己的property , 都已经实现ioc注入
TransactionTemplate必须指定transactionManager
DataSourceTransactionManager必须指定数据源dataSource
ok, 现在进行测试:
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.AccountService;
public class TransctionTest {
@Test
public void testNoTransaction(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextTranscation.xml");
AccountService account = (AccountService) context.getBean("accountService");
//Tom 向 Marry 转账1000
account.transfer("Tom", "Marry", 1000);
}
}
上述用到的数据库
CREATE TABLE `account` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`money` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES ('1', 'Tom', '8000');
INSERT INTO `account` VALUES ('2', 'Marry', '12000');