Spring中事务(基于xml && 基于注解)

Spring事务

一、基本概念

1、事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务是恢复和并发控制的基本单位。

2、特性ACID:原子性:整体。 一致性:完成。隔离性:并发。持久性:结果。

3、隔离问题:

脏读:一个事务读到另一个事务没有提交的数据

不可重复读:一个事务读到另一个事务已提交的数据(update)

虚读(幻读):一个事务读到另一个事务已提交的数据(insert)

4、隔离级别:

      readuncommitted:读未提交。存在3个问题

      readcommitted:读已提交。解决脏读,存在2个问题

      repeatableread:可重复读。解决:脏读、不可重复读,存在1个问题。

      serializable:串行化。都解决,单事务。

5、Spring中事务的包:spring-tx-3.2.0.RELEASE.jar

6、事务的三个顶级接口:

 PlatformTransactionManager(平台事务管理器):spring要管理事务,必须使用事务管理器,进行事务配置时,必须配置事务管理器。

TransactionDefinition事务详情(事务定义、事务属性):spring用于确定事务具体详情,例如:隔离级别、是否只读、超时时间等。进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。

TransactionStatus事务状态:spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。spring底层根据状态进行相应操作。


7、事务管理器只是一个接口,开发的时候要使用它的实现类。

PlatformTransactionManager平台事务管理器 中两个常见的事务管理类

1、DataSourceTransactionManager,jdbc开发时事务管理器,采用JdbcTemplate

2、HibernateTransactionManager,hibernate开发时事务管理器,整合hibernate

【注意】事务管理器,通过“事务详情”,获得“事务状态”,从而管理事务。

事务详情 TransactionDefinition 中定义的一些信息:

1、PROPAGATION_REQUIRED, required , 必须  【默认值】支持当前事务,A如果有事务,B将使用该事务。    如果A没有事务,B将创建一个新的事务。

2、PROPAGATION_REQUIRES_NEW, requires_new ,必须新的。 如果A有事务,将A的事务挂起,B创建一个新的事务。    如果A没有事务,B创建一个新的事务。

3、PROPAGATION_NESTED,nested ,嵌套。A和B底层采用保存点机制,形成嵌套事务。

 

二、基于xml的事务配置

在Spring xml配置AOP自动生成代理,进行事务管理。

1、建表

create table account(

  id int primary key auto_increment,

  username varchar(50),

  money int

);

insert into account(username,money) values('dianer','100');

insert into account(username,money) values('Lily','100');

 

2、导入Jar包

Spring 4+1

spring-beans-3.2.0.RELEASE.jar

spring-context-3.2.0.RELEASE.jar

spring-core-3.2.0.RELEASE.jar

spring-expression-3.2.0.RELEASE.jar

com.springsource.org.apache.commons.logging-1.1.1.jar

AOP 4个

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

spring-aop-3.2.0.RELEASE.jar

spring-aspects-3.2.0.RELEASE.jar

数据两个

spring-jdbc-3.2.0.RELEASE.jar

spring-tx-3.2.0.RELEASE.jar

驱动包

mysql-connector-java-5.1.28-bin.jar
连接池

com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

 

3、DAO接口

public interface AccountDAO {
	//汇款是pay,收款是Receipt
	
	public void pay(String outer,Integer money);
	public void receipt(String inner,Integer money);

}


4、DAO接口的实现类

public class AccountDAOImpl extends JdbcDaoSupport implements AccountDAO {

	/* (non-Javadoc)
	 * @see com.Lily.SpringLearning.J_tx_xml.AccountDAO#pay(java.lang.String, java.lang.Integer)
	 */
	@Override
	public void pay(String outer, Integer money) {
		// TODO Auto-generated method stub
		this.getJdbcTemplate().update("update account set money = money - ? where username = ?", money,outer);
		
	}

	/* (non-Javadoc)
	 * @see com.Lily.SpringLearning.J_tx_xml.AccountDAO#receipt(java.lang.String, java.lang.Integer)
	 */
	@Override
	public void receipt(String inner, Integer money) {
		// TODO Auto-generated method stub
		this.getJdbcTemplate().update("update account set money = money + ? where username = ?", money,inner);
		
	}

}


5、Service接口

public interface Ser {

	//转账服务
	
	public void transfer(String outer,String inner,Integer money);
}


6、Service实现类

public class AccountSerImpl implements Ser {

	/* (non-Javadoc)
	 * @see com.Lily.SpringLearning.J_tx_xml.Ser#transfer(java.lang.String, java.lang.String, java.lang.Integer)
	 */
	private AccountDAO accountDao;
	
	
	
	public AccountDAO getAccountDao() {
		return accountDao;
	}



	public void setAccountDao(AccountDAO accountDao) {
		this.accountDao = accountDao;
	}



	@Override
	public void transfer(String outer, String inner, Integer money) {
		// TODO Auto-generated method stub
		accountDao.pay(outer, money);
		//模拟故障
		//int i=1/0;
		accountDao.receipt(inner, money);
	}

}


7、配置xml文件 

头部加上:

xmlns:tx=http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx

 http://www.springframework.org/schema/tx/spring-tx.xsd


这里采用的是读取properties文件的方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       					   http://www.springframework.org/schema/aop 
       					   http://www.springframework.org/schema/aop/spring-aop.xsd
       					   http://www.springframework.org/schema/context 
       					   http://www.springframework.org/schema/context/spring-context.xsd
       					   http://www.springframework.org/schema/tx 
       					   http://www.springframework.org/schema/tx/spring-tx.xsd">
	
	
	
	
	<context:property-placeholder location="classpath:com/Lily/SpringLearning/I_c3p0/JdbcInfo.properties" />
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>	
		<property name="user" value="${jdbc.user}"></property>
		<property name="password"  value="${jdbc.password}"></property>
	</bean>
	
	
	
	<bean id="accountDao" class="com.Lily.SpringLearning.J_tx_xml.AccountDAOImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	
	<bean id="accountService" class="com.Lily.SpringLearning.J_tx_xml.AccountSerImpl">
		<property name="accountDao" ref="accountDao"></property>
	</bean>
	
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
		</tx:attributes>	
	</tx:advice>
	
	<aop:config>
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.Lily.SpringLearning.J_tx_xml..*.*(..))"/>
	</aop:config>
	
		

</beans>


8、编写测试类

 

/**
 * 
 */
package com.Lily.SpringLearning.J_tx_xml;

import static org.junit.Assert.*;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月26日
 * @time     下午9:02:32
 * @Version  1.0
 * @email    lilylee_1213@foxmail.com
 *
 */
public class txTest {

	@Test
	public void test() {
		String xmlPath = "com/Lily/SpringLearning/J_tx_xml/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		Ser accountService =  (Ser) applicationContext.getBean("accountService");
		accountService.transfer("dianer", "Lily", 6);
	}

}

这里出了一个小插曲,第一次运行的时候报错,因为

Ser accountService =  (Ser)applicationContext.getBean("accountService");

前面应该是Service的接口,而不是实现类,这个要注意。

 

三、基于注解的事务

注解加在两个地方

1、Service的实现类@Transactional(propagation=Propagation.REQUIRED , isolation =Isolation.DEFAULT)

2、修改xml,  <tx:annotation-driventransaction-manager="txManager"/>,将管理器交给Spring,底层使用CGLIB代理。

 

/**
 * 
 */
package com.Lily.SpringLearning.J_tx_anno;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/** 
 * * 
 * @author   LilyLee
 * @date     2017年6月26日
 * @time     下午8:37:28
 * @Version  1.0
 * @email    lilylee_1213@foxmail.com
 *
 */

@Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)

public class AccountSerImpl implements Ser {

	/* (non-Javadoc)
	 * @see com.Lily.SpringLearning.J_tx_xml.Ser#transfer(java.lang.String, java.lang.String, java.lang.Integer)
	 */
	private AccountDAO accountDao;
	
	
	
	public AccountDAO getAccountDao() {
		return accountDao;
	}



	public void setAccountDao(AccountDAO accountDao) {
		this.accountDao = accountDao;
	}



	@Override
	public void transfer(String outer, String inner, Integer money) {
		// TODO Auto-generated method stub
		accountDao.pay(outer, money);
		//模拟故障
		//int i=1/0;
		accountDao.receipt(inner, money);
	}

}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       					   http://www.springframework.org/schema/aop 
       					   http://www.springframework.org/schema/aop/spring-aop.xsd
       					   http://www.springframework.org/schema/context 
       					   http://www.springframework.org/schema/context/spring-context.xsd
       					   http://www.springframework.org/schema/tx 
       					   http://www.springframework.org/schema/tx/spring-tx.xsd">
	
	
	
	
	<context:property-placeholder location="classpath:com/Lily/SpringLearning/I_c3p0/JdbcInfo.properties" />
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>	
		<property name="user" value="${jdbc.user}"></property>
		<property name="password"  value="${jdbc.password}"></property>
	</bean>
	
	
	
	<bean id="accountDao" class="com.Lily.SpringLearning.J_tx_anno.AccountDAOImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	
	<bean id="accountService" class="com.Lily.SpringLearning.J_tx_anno.AccountSerImpl">
		<property name="accountDao" ref="accountDao"></property>
	</bean>
	
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<tx:annotation-driven transaction-manager="txManager"/>
		

</beans>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值