关闭

Spring-事务处理

175人阅读 评论(0) 收藏 举报
分类:
原始JDBC实现事务的代码如果是通过切面实现,大概是下面这样的。
public void transferMoney(){
	try{
		//@Before
		conn = dataSource.getConnection(); //每个事务Connection需要独立
		conn.setAutoCommit(false);
		
		//ProceedingJoinPoint.proceed()
		//实现事务中的业务逻辑操作
		
		//@AfterReturning
		conn.commit();//正常执行完事务后提交
	}catch(SQLException e){
		//@AfterThrowing
		e.printStackTrace();
		if(conn != null){
			try{
				conn.rollback(); //回滚未完成的数据库操作
			}catch(SQLException e){
				..
			}
		}
	}finally{
		//@After 后置通知
		if(conn!=null){
			try{
				conn.cloes();
			}catch(SQLException e){
				...
			}
		}
	}
}

使用Spring执行事务步骤:

1.配置事务管理器
<bean id="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2.启用事务注解(需要加入tx命名空间)
<tx:annotation-driven transaction-manager="transactionManager"/>
3.添加@Transactional注解
只需要在需要使用事务的函数上面添加注解,即可。
@Transactional
public void transferMoney(){}

事务的传播属性

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。
是继续在现有的事务中运行,还是开启一个新的事务等。
Spring定义了7种传播行为(用枚举实现):注意上面提到Transactional是修饰方法的,下面的情况都是对当前执行的方法的说明。
REQUIRED(默认) :如果有一个既有的事务,则调用新方法则继续使用已有的的事务。若没有则开启新事务。
REQUIRED_NEW:如果有新的事务,则新方法会将其挂起。并开启自己的事务。
后面几个不常用
SUPPORTS:如果有事务在运行,则当前方法在这个事务内运行,否则可以不在事务中运行。
NOT_SUPPORED:当前方法不支持,若有事务在运行,则将其挂起。
MANDATORY:当前方法必须运行在事物内部,如果没有正在运行的事务则异常。
NEVER:当前方法不运行在事务中,若有运行的事务则抛出异常。
NESTED:若有事务在运行,当前方法就应该在这个事务中嵌套事务内运行,否则就启动一个新的事务,并在他自己的事务内运行。
@Transactional(propagation=Propagation.REQUIRED)
public void transferAll(){
transferMoney(); //transferAll本身是有事务的,但是transferMoney也是有事务的,这种情况就适合上面描述的传播方式啦。
}

事务的其他特性

隔离级别: isolation=Isolation.READ_COMMITTED
指定回滚异常、不会滚异常(默认只有运行时异常回滚),也可以进行特殊的设置。
运行时异常不回滚设置例:@Transactional(noRollbackFor={RuntimeException.class})
指定事务是否可以更改数据:@Transactional(readOnly=true) 设置为true时,会被优化为无锁,相当于不使用事务。

指定timeout时间(单位是秒):@Transactional(timeout=1)指定回滚前到超时时间。

用xml配置事务

xml配置方式稍微有些麻烦,但是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"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
	<context:property-placeholder location="c3p0.properties"/>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${user}"></property>
		<property name="password" value="${password}"></property>
		<property name="driverClass" value="${driverClass}"></property>
		<property name="jdbcUrl" value="${jdbcUrl}"></property>
		<property name="initialPoolSize"  value="${initialPoolSize}"></property>
		<property name="maxPoolSize" value="${maxPoolSize}"></property>
	</bean>
	<!-- 配置JdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 1.配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 2.配置事务属性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transferMoney" propagation="REQUIRED" isolation="DEFAULT" read-only="false" timeout="-1" />
		</tx:attributes>
	</tx:advice>
	
	<!-- 3.配置事务切入点,关联切入点和事务 -->
	<aop:config>
		<aop:pointcut id="txPointcut" expression="execution(public void test.DbTransaction.transferMoney())"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
	</aop:config>
</beans>

<完>

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    最新评论