1 声明式事物是对数据库进行一系列操作时要么全部操作完成,要么全部不操作。分自动提交事务,显式事务,隐式事务,批处理事务四种运行模式。
自动提交事务:Meiz每条单独的语句都是一个事务,是T-SQL默认的事务。
显式事务:每个事务以BEGIN TRANSACTION语句显式开始,以COMMIT或ROLLBACK语句显式结束。
隐式事务:在前一个事务完成是新事务隐式启动,但每一个事务仍以Commit或ROLLBACK语句显式完成。
批处理级事务:只能应用于多个活动结果集。
Spring的事务管理是通过AOP代理实现的。
2 DEMO:该下均采用声明式事务,配置简单,且无侵入性。
2.1 使用注解的方式
使用注解的方式,在需要使用声明式事物的地方添加注解,配置文件中设置声明式管理器类,简单明了。注意不要在接口中使用声明式事务注解,注解不能继承,也就是说实现类不会具有声明式的特性,这样在接口中使用声明式注解毫无意义。可以在类的public方法中设置声明式事务,在方法中的设置将覆盖类中的声明式事务的设置,具体说明看代码中的注释。
配置文件:
<!-- 声明式事物配置----使用注解的方式-->
<!-- 配置事物管理器 JDBC及iBATIS、MyBatis框架事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 启动声明式事务行为,如果使用transactionManager名称来定义 声明式事物,则在下方可省略transaction-manager属性设置,
系统自动会找bean的id为transactionManager的Bean -->
<tx:annotation-driven transaction-manager="transactionManager"/>
类定义:
//添加注解,启动声明式管理
@Transactional
public class UserDaoImpl implements UserDao{
private SqlSessionTemplate sqlSession;
@Override
public List<User> selectUser() {
// TODO Auto-generated method stub
User user=new User();
user.setName("大虾1");
user.setPwd("1234");
sqlSession.insert("cn.sxt.vo.user.mapper.add", user);
sqlSession.delete("cn.sxt.vo.user.mapper.remove");
return sqlSession.selectList("cn.sxt.vo.user.mapper.selectAll");
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
}
2.2 使用配置的方式。匹配需要声明事务的操作,通过一个通知器与声明式管理器绑定在一起,当声明事务的操作执行时,绑定的管理器将会执行。
配置文档:
<!-- 配置事物管理器 JDBC及iBATIS、MyBatis框架事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 利用通配符配置事务声明方法 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--配置那些方法使用什么样的事物,配置事物的传播特性-->
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="insert" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="get" read-only="true"/>
<!--拦截任何方法-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 声明事务的位置 与AOP配置切入点表达式类似-->
<aop:pointcut expression="execution(* cn.sxt.dao.impl.*.*(..))" id="point"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>
默认设置:
图片摘自官方文档。
tx:advice属性说明:
tx:advice:id用于指定此通知的名字, transaction-manager用于指定事务管理器。
tx:method:用于定义事务属性即相关联的方法名;
name:定义与事务属性相关联的方法名,将对匹配的方法应用定义的事务属性,可以使用“”通配符来匹配一组或所有方法,如“save”将匹配以save开头的方法,而“*”将匹配所有方法;
propagation:事务传播行为定义,默认为“REQUIRED”,表示Required,其值可以通过TransactionDefinition的静态传播行为变量的“PROPAGATION_”后边部分指定,如“TransactionDefinition.PROPAGATION_REQUIRED”可以使用“REQUIRED”指定;
isolation:事务隔离级别定义;默认为“DEFAULT”,其值可以通过TransactionDefinition的静态隔离级别变量的“ISOLATION_”后边部分指定,如“TransactionDefinition. ISOLATION_DEFAULT”。
ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别;ISOLATION_READ_UNCOMMITTED:未提交读;
ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个;
ISOLATION_REPEATABLE_READ:可重复读;
ISOLATION_SERIALIZABLE:序列化。
timeout:事务超时时间设置,单位为秒,默认-1,表示事务超时将依赖于底层事务系统;
read-only:事务只读设置,默认为false,表示不是只读;
rollback-for:需要触发回滚的异常定义,以“,”分割,默认任何RuntimeException 将导致事务回滚,而任何Checked Exception 将不导致事务回滚;异常名字定义和TransactionProxyFactoryBean中含义一样
no-rollback-for:不被触发进行回滚的 Exception(s);以“,”分割;异常名字定义和TransactionProxyFactoryBean中含义一样;
public List<User> selectUser() {
// TODO Auto-generated method stub
User user=new User();
user.setName("大虾1");
user.setPwd("1234");
sqlSession.insert("cn.sxt.vo.user.mapper.add", user);
sqlSession.delete("cn.sxt.vo.user.mapper.remove");
return sqlSession.selectList("cn.sxt.vo.user.mapper.selectAll");
}
编程式事务时不推荐的,即使有很少事务操作,Spring发展到现在,没有理由使用编程式事务,只有在为了深入理解Spring事务管理才需要学习编程式事务使用。
推荐使用声明式事务,而且强烈推荐使用tx:tags方式的声明式事务,因为其是无侵入代码的,可以配置模板化的事务属性并运用到多个项目中。而@Transaction注解事务,可以使用,不过作者更倾向于使用tx:tags声明式事务。
部分摘自:http://jinnianshilongnian.iteye.com/blog/1442376感谢大神分享。
3 Spring可以将事务管理交给第三方,以Hibernate为例:
如果应用程序的持久化是通过Hibernate实习的,那么你需要使用HibernateTransactionManager。对于Hibernate3,需要在Spring上下文定义中添加如下的声明:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
sessionFactory属性需要装配一个Hibernate的session工厂,HibernateTransactionManager的实现细节是它将事务管理的职责委托给org.hibernate.Transaction对象,而后者是从Hibernate Session中获取到的。当事务成功完成时,HibernateTransactionManager将会调用Transaction对象的commit()方法,反之,将会调用rollback()方法。
Spring中具体控制的代码在TransactionAspectSupport类 invokeWithinTransaction方法
未完待续。。。