好多东西网上都有,事务的特点就不说了, 直接来个简单的列子比较好.
spring中事务有两种实现方式, 一种是编程式事务, 一种是声明式事务
我个人来说喜欢用编程式事务, 总感觉明了一些, 可能只是习惯吧
新建一个springDemo项目
![](https://img.haomeiwen.com/i3055930/e69bd14baf9ba999.png)
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="accountDao" class="dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="accountService" class="service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
<!--事务模版-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"></property>
</bean>
<!--数据源事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
事务模版和数据源管理器都有自己的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');
网友评论