Spring-事务处理
2016-05-30 23:54
423 查看
原始JDBC实现事务的代码如果是通过切面实现,大概是下面这样的。
<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也是有事务的,这种情况就适合上面描述的传播方式啦。
}
指定回滚异常、不会滚异常(默认只有运行时异常回滚),也可以进行特殊的设置。
运行时异常不回滚设置例:@Transactional(noRollbackFor={RuntimeException.class})
指定事务是否可以更改数据:@Transactional(readOnly=true) 设置为true时,会被优化为无锁,相当于不使用事务。
指定timeout时间(单位是秒):@Transactional(timeout=1)指定回滚前到超时时间。
<完>
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>
<完>
相关文章推荐
- [原创]java WEB学习笔记29:Cookie Demo 之自动登录
- Java编程思想第四版第十章学习——内部类(1)
- 华为机试---蛇形矩阵
- JavaMail技术
- Java NIO使用及原理分析
- eclipse提交项目到github
- java之io之File类的list()方法过滤目录的使用
- Java之------IO从基础到加强(二)
- Spring线程池开发实战
- Java匿名类
- eclipse里面添加hive maven相关依赖报错
- spring 细节
- java学习的第一课
- maven搭建ssm分模块框架+ehcache (myeclipse版) (五)
- RxJava Subscription 自动取消订阅
- Struts2上课笔记
- 导入JFrame时eclipse编译报错
- SSM之DAO部分Spring与MyBatis整合
- 三种初级排序算法(冒泡、选择、直接插入)java实现及其性能比较
- Spring注解