spring学习笔记07:AOP事务注解版

一、导包(下面用一个转账的例子来实现):


  		UTF-8
  		4.12
  		0.9.5.2
  		5.1.38
  		5.0.8.RELEASE
  		1.8.10
  
  
  
  
			org.aspectj
			aspectjweaver
			${aspect.version}
		
		
			org.aspectj
			aspectjrt
			${aspect.version}
		
  
  
  
			org.springframework
			spring-context
			${spring.version}
		
	
		
		    org.springframework
		    spring-jdbc
		    ${spring.version}
		
	
		
			org.springframework
			spring-test
			${spring.version}
			test
		
		
	
	    mysql
	    mysql-connector-java
	    ${mysql.version}
	
		
		
			com.mchange
			c3p0
			${c3p0.version}
		
  
    
      junit
      junit
      ${junit.version}
      test
    
  

二、创建Account实体类

public class Account {
	private int id;
	private String name;
	private double money;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	
}

三、创建对应的dao

接口

public interface AccountDao {
	//减钱操作
	public void reduce(int id,double money);
	//加钱操作
	public void increase(int id,double money);
}

实现类(我继承的JdbcDaoSupport,可以直接获取JdbcTemplate)

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
	//减钱操作
	@Override
	public void reduce(int id, double money) {
		String sql = "update t_account set money=money-? where id=?";
		this.getJdbcTemplate().update(sql, money,id);
	}
	//加钱操作
	@Override
	public void increase(int id, double money) {
		String sql = "update t_account set money=money+? where id=?";
		this.getJdbcTemplate().update(sql, money,id);
	}

}

四、创建对应的service

接口

public interface AccountService {
	//转账
	public void transfer(int id1, int id2, double money);
}

实现类

//@Transactional开启事务管理,在类前面表示整个的所有方法都开启事务管理
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
public class AccountServiceImpl implements AccountService{
	@Resource(name="accountDao")
	private AccountDao accountDao;
	
	
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}


	@Override
	public void transfer(int id1, int id2, double money) {
		//先减钱
		accountDao.reduce(id1,money);
		
		//增加异常
		//int a = 1/0;
		
		//再加钱
		accountDao.increase(id2, money);
	}

}

五、创建对一个数据库

spring学习笔记07:AOP事务注解版_第1张图片
插入两条测试数据:
spring学习笔记07:AOP事务注解版_第2张图片

六、配置文件(注解事务的配置文件比非注解事务少了很多配置的步骤,开启注解即可



	
	
	
	
		
		
		
		
	
	
	
		
	
	
	
		
	
	
	
	
	
	
		
	
	
	

isolation是隔离级别 propagation是传播行为 ;

aop的隔离级别和传播行为

七、测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-transaction.xml")
public class TestTransaction {
	@Resource(name="accountService")
	private AccountService accountService;
	
	@Test
	public void test1() {
        //转账50
		accountService.transfer(1, 2, 50);
	}
}

八、测试结果

正常情况下,执行测试代码,查看数据库,转账成功
转账过程出现异常(往AccountServiceImpl的transfer方法加入int a=1/0;),没有增加事务管理的话会出现A给B转钱,A扣了钱,B 却没有收到钱;增加事务管理后出现异常数据库会回滚,所以不会发生丢钱的结果:

spring学习笔记07:AOP事务注解版_第3张图片

注意:@Transactional放置的位置既可以是类前面,也可以是方法前面,放在类前面表示该类所有方法都开启事务管理,放在方法前面表示该方法开启事务管。
当多个方法需要开启事务管理时,最后在类前面设置注解@Transactional,如果类中的方法大多数的readOnly=true,那类前面就设置readOnly=true,然后在特殊方法设置添加@Transactional并设置readOnly=true;反过来也是一样(有点类似全局变量和局部变量的感觉,遵循就近原则)

你可能感兴趣的:(spring)