Spring--声明式事务

来源:互联网 发布:吸尘器手持 卧式 知乎 编辑:程序博客网 时间:2024/06/07 13:46

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"/>

类定义:

//添加注解,启动声明式管理@Transactionalpublic 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>

默认设置:
这里写图片描述
图片摘自官方文档。
属性说明:
:id用于指定此通知的名字, transaction-manager用于指定事务管理器。
:用于定义事务属性即相关联的方法名;
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事务管理才需要学习编程式事务使用。
推荐使用声明式事务,而且强烈推荐使用方式的声明式事务,因为其是无侵入代码的,可以配置模板化的事务属性并运用到多个项目中。而@Transaction注解事务,可以使用,不过作者更倾向于使用声明式事务。
部分摘自: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()方法。

未完待续。。。

原创粉丝点击