一、创建数据库并插入数据
create database spring_transaction;use spring_transaction;create table account(id int primary key auto_increment,username varchar(50),money int);insert into account(username,money) values('jack',1000);insert into account(username,money) values('rose',1000);
二、无事务下操作数据
1、项目结构及引用的相应jar包
2、创建接口AccountDao及其实现类AccountDaoImpl(实现类继承自JdbcDaoSupport,可以直接获得jdbc模板对象)
package com.hujp.dao;/** * Created by JiaPeng on 2015/11/4. */public interface AccountDao { /** * 收款(入) * @param inUser * @param money */ public void in(String inUser,int money); /** * 汇款(出) * @param outUser * @param money */ public void out(String outUser,int money);}
package com.hujp.dao.impl;import com.hujp.dao.AccountDao;import org.springframework.jdbc.core.support.JdbcDaoSupport;/** * Created by JiaPeng on 2015/11/4. */public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void in(String inUser, int money) { this.getJdbcTemplate().update("UPDATE account SET money=money+? WHERE username=?",money,inUser); } @Override public void out(String outUser, int money) { this.getJdbcTemplate().update("UPDATE account SET money=money-? WHERE username=?", money, outUser); }}
3、创建接口AccountService及其实现类AccountServiceImpl(实现类里需要有AccountDao字段,在spring配置中注入)
package com.hujp.service;/** * Created by JiaPeng on 2015/11/4. */public interface AccountService { public void transfer(String outUser,String inUser,int money);}
package com.hujp.service.impl;import com.hujp.dao.AccountDao;import com.hujp.service.AccountService;/** * Created by JiaPeng on 2015/11/4. */public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void transfer(String outUser, String inUser, int money) { this.accountDao.out(outUser, money); //模拟断电 //int m=2/0; this.accountDao.in(inUser, money); }}
4、配置文件applicationContext.xml
package com.hujp;import com.hujp.service.AccountService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * Created by JiaPeng on 2015/11/4. */public class TestApp { @Test public void demo1() { String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath); AccountService accountService= (AccountService) applicationContext.getBean("accountService"); accountService.transfer("jack","rose",100); }}
5、代码结构图
二、手动操作事务管理数据库
事务管理主要在service层,所以需要改动两个文件即可,一个是application配置文件,另一个是AccountServiceImpl实现类
在实现类中,事务模板对象执行execute方法,重写事务返回无结果集抽象类TransactionCallbackWithoutResult的抽象方法doInTransactionWithoutResult达到事务管理目的
package com.hujp.service.impl;import com.hujp.dao.AccountDao;import com.hujp.service.AccountService;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;/** * Created by JiaPeng on 2015/11/4. */public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } //事务操作一般在service层进行操作 private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } @Override public void transfer(final String outUser,final String inUser, final int money) { //无结果集操作 this.transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { accountDao.out(outUser, money); //模拟断电 //int m=2/0; accountDao.in(inUser, money); } }); }}
三、使用工厂bean创建代理管理事务
继续使用无事务下操作数据库的工程,测试类中accountService对象由代理类创建,并在配置文件配置工厂bean内配置事务
主要改两个文件,一个是测试类,其中获得service对象通过工厂bean获得;另一个是在applicationContext.xml文件中配置工厂bean和事务操作
package com.hujp;import com.hujp.service.AccountService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * Created by JiaPeng on 2015/11/4. */public class TestApp { @Test public void demo1() { String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath); AccountService accountService= (AccountService) applicationContext.getBean("proxyService"); accountService.transfer("jack","rose",100); }}
PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ,+java.lang.ArithmeticException