Sping中的aop事务

Spring封装了事务管理代码

1.事务操作依旧是:打开事务、提交事务、回滚事务

2.事务的操作对象

 (1)因为在不同平台,操作事务的代码各不相同.spring提供了一个接口:

    PlatformTransactionManager 接口

  • DataSourceTransactionManager

  • HibernateTransitionmanager

  注意:在spring中玩事务管理.最为核心的对象就是TransactionManager对象

(2)spring管理事务的属性介绍

 1.事务的隔离级别                

  • 1 读未提交

  • 2 读已提交

  • 4 可重复读

  • 8 串行化

  2.是否只读

  • true 只读
  • false 可操作

 3. 事务的传播行为

  1. PROPAGATION_REQUIRED:如果当前没事务,就创建一个新事务,如果当前存在事务,就加入该事务,是最常用的设置
  2. PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,以非事务执行
  3. PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
  4. PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  6. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

  
       

Spring管理事务方式

三种方式:编码式xml配置(aop)、注解配置(aop)

(1)编码式(了解)

以转账为例:

1.将核心事务管理器配置到spring容器

<!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 -->
	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

2.配置TransactionTemplate模板

<!-- 事务模板对象 -->
	<bean name="transactionTemplate"class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
	</bean>

3.将事务模板注入Service

<!-- 3.Service -->
	<bean name="accountService" class="cn.hncu.service.AccountServiceImpl">
		<property name="ad" ref="accountDao"></property>
		<property name="tt" ref="transactionTemplate"></property>
	</bean>

4.在Service中调用模板

<!-- 3.Service -->
	<bean name="accountService" class="cn.hncu.service.AccountServiceImpl">
		<property name="ad" ref="accountDao"></property>
		<property name="tt" ref="transactionTemplate"></property>
	</bean>

  (2)xml配置(aop)

   1.导包:

               

  2.导入新的约束(tx)

  • beans: 最基本

  • context:读取properties配置

  • aop:配置aop

  • tx:配置事务通知

   

  3.配置通知

<!-- 配置事务通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 以方法为单位,指定方法应用什么事务属性 isolation:隔离级别 propagation:传播行为 read-only:是否只读 -->
			<!-- REPEATABLE_READ 可重复读 READ_COMMITTED 读已提交 READ_UNCOMMITTED 读未提交 SERIALIZABLE 
				串行化 -->
			<tx:method name="aave*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="persist*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="update*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="modify*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="delete*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="remove*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
			<tx:method name="get*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="true" />
			<tx:method name="find*" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="true" />
			<tx:method name="transfer" isolation="REPEATABLE_READ"
				propagation="REQUIRED" read-only="false" />
		</tx:attributes>
	</tx:advice>

4.配置将通知织入目标

<!-- 配置织入 -->
	<aop:config>
		<!-- 配置切点表达式 -->
		<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))"
			id="txPc" />
		<!-- 配置切面 : 通知+切点 advice-ref:通知的名称 pointcut-ref:切点的名称 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
	</aop:config>


 (3)注解配置(aop)

  1.导包

  2.导入新的约束(tx)

 3.开启注解管理事务

<!-- 开启使用注解管理aop事务 -->
<tx:annotation-driven/>

4.使用注解

dao:

package cn.hncu.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
  
	@Override
	public void increaseMoney(Integer id, Double money) {
		
		getJdbcTemplate().update("update t_account set money =money+? where id=? ", money,id);
	}

	@Override
	public void decreaseMoney(Integer id, Double money) {
		
		getJdbcTemplate().update("update t_account set money =money-? where id=? ", money,id);
	}

}

service:

package cn.hncu.service;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import cn.hncu.dao.AccountDao;


@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {

	
	private AccountDao ad;
	private TransactionTemplate tt;
	
	public AccountDao getAd() {
		return ad;
	}

	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	public TransactionTemplate getTt() {
		return tt;
	}

	public void setTt(TransactionTemplate tt) {
		this.tt = tt;
	}

	/*@Override
	@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
	public void transfer(final Integer from,final Integer to,final Double money) {
		//减钱
		ad.decreaseMoney(from, money);
		//int i = 1/0;
		//加钱
		ad.increaseMoney(to, money);
}*/
	
	@Override
	public void transfer( final Integer from,final Integer to,final Double money) {
		// TODO Auto-generated method stub
		
	    tt.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
			   
				//减钱
				ad.decreaseMoney(from, money);
				
				//加钱
				ad.increaseMoney(to, money);   
				
			}
		});
		
		
	    //1.打开事务
	    //2.调用doInTransactionWithoutResult方法
	    //3.提交事务
	} 
  
}

测试:

package cn.hncu.tx;


import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.hncu.service.AccountService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Demo2 {
	@Resource(name="accountService")
	private AccountService as;
	
	@Test
	public void fun1(){
		
		as.transfer(1, 2, 100d);
		
	}
}


   

猜你喜欢

转载自blog.csdn.net/lx678111/article/details/83587798