事务
一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。而 不是给 MyBatis 创建一个新的特定的事务管理器,MyBatis-Spring 利用了存在于 Spring 中的 DataSourceTransactionManager。
一旦 Spring 的 PlatformTransactionManager 配置好了,你可以在 Spring 中以你通常的做 法来配置事务。@Transactional 注解和 AOP(Aspect-Oriented Program,面向切面编程,译 者注)样式的配置都是支持的。在事务处理期间,一个单独的 SqlSession 对象将会被创建 和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。
一旦事务创建之后,MyBatis-Spring 将会透明的管理事务。在你的 DAO 类中就不需要额 外的代码了。
标准配置
要 开 启 Spring 的 事 务 处 理 , 在 Spring 的 XML 配 置 文 件 中 简 单 创 建 一 个 DataSourceTransactionManager 对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
指定的 DataSource 一般可以是你使用 Spring 的任意 JDBC DataSource。这包含了连接 池和通过 JNDI 查获得的 DataSource。
要注意, 为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的 是同一个数据源,否则事务管理器就无法工作了。
容器管理事务
如果你正使用一个 JEE 容器而且想让 Spring 参与到容器管理事务(Container managed transactions,CMT,译者注)中,那么 Spring 应该使用 JtaTransactionManager 或它的容 器指定的子类来配置。做这件事情的最方便的方式是用 Spring 的事务命名空间:
<tx:jta-transaction-manager />
在这种配置中,MyBatis 将会和其它由 CMT 配置的 Spring 事务资源一样。Spring 会自动 使用任意存在的容器事务,在上面附加一个 SqlSession。如果没有开始事务,或者需要基 于事务配置,Spring 会开启一个新的容器管理事务。
注 意 , 如 果 你 想 使 用 CMT , 而 不 想 使 用 Spring 的 事 务 管 理 , 你 就 必 须 配 置 SqlSessionFactoryBean 来使用基本的 MyBatis 的 ManagedTransactionFactory 而不是其 它任意的 Spring 事务管理器:
<bean id="sqlSessionFactory" class="batis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionFactory">
<bean class="org.ansaction.managed.ManagedTransactionFactory" />
</property> 
</bean>
编程式事务管理
MyBatis 的 SqlSession 提供指定的方法来处理编程式的事务。 但是当使用 MyBatis-Spring 时, bean 将会使用 Spring 管理的 SqlSession 或映射器来注入。 那就是说 Spring 通常是处理 事务的。
你 不 能 在 Spring 管 理 的 SqlSession 上 调 用 SqlSessionmit() , llback() 或 SqlSession.close() 方 法 。 如 果 这 样 做 了 , 就 会 抛
出 UnsupportedOperationException 异常。注意在使用注入的映射器时不能访问那些方法。
无论 JDBC 连接是否设置为自动提交, SqlSession 数据方法的执行或在 Spring 事务之外 任意调用映射器方法都将会自动被提交。
如果你想编程式地控制事务,请参考 Spring 手册的 10.6 节。这段代码展示了如何手动 使用在 10.6.2 章节描述的 PlatformTransactionManager 来处理事务。
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = Transaction(def);
try {
userMapper.insertUser(user);
}
catch (MyException ex) {
throw ex;
}
txManagermit(status);
注意这段代码展示了一个映射器,但它也能和 SqlSession 一起使用。
  1、事务是指一系列独立的操作,但在概念上具有原子性。 比如转账:A账号-100, B账号+100,完成。这两个操作独立是没问题的。 但在逻辑上,要么全部完成,要么一起失败。
  1)jdbc事务:每个Connection都带有一个事务,只是默认被设置为自动提交。一个连接可以有多个事务。对于JDBC,只有在同一个连接内,才有讨论是否提交的前提。
  2)Hibernate事务:本质上也是使用JDBC来处理事务。但是不是直接操作,而是使用Session来操作
事务。Tranction();
  ####事务应该要在service层(也可以叫事务层)进行控制。
为什么用Spring来进行事务控制?
  如果要手动进行控制事务的话,对于JDBC,service层需要Connection;对于Hibernate,serivice层需要 Session。若一个项目要实现JDBC和Hibernate或其他的互换,我们要做Service层修改很多东西;而且对于Service层来说,他 应该关心的不应该是这些,而是业务逻辑。因此,首先手动控制不能实现组件的替换,其次这些API也不应该出现在service层,但是Spring的 IOC很好的解决了这样的问题。
  2、JavaEE传统事务有两种策略:全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、JBoss等)。局部事务和底层采用的持久化技术有关:当采用JDBC持久化技术时,需要使用Connetion对象来操作事务;而采用Hibernate持久化技术时,需要使用Session对象来操作事务。
  全局事务可以跨多个事务性的资源(典型例子是关系数据库和消息队列);使用局部事务,应用服务器不需要参与事务管理,因此不能保证跨多个事务性资源的事务的正确性。当然,实际上大部分应用都使用单一事务性的资源。
  Spring事务策略是通过PlatformTransactionManager接口体现的,该接口是Spring事务策略的核心,是一个与任何事务策略分离的接口,随着底层不
同事务策略的切换,应用必须采用不同的实现类。结合Spring的IoC容器,可以向该接口注入相关的平台特性。
  3、Spring的事务管理,主要有两种方式实现,一种是在代码中编写(编程式事务管理),一种是声明式事务(又可分为AOP式事务管理和注解式事务管理)。在代码中编写要更加细粒度,而很多时候我们只需要简单的事务处理,那就可以用声明式事务。
Spring的事务管理器:
事务管理器实现:org.springframework.jdbc.datasource.DataSourceTransactionManager
目标:在JDBC DataSource中管理事务
(须注入数据源datasource  Bean参数)
事务管理器实现:hibernate.HibernateTransactionManager
目标:管理Hibernate事务
(须注入SessionFactory Bean参数)
事务管理器实现:jdo.JdoTransactionManager
目标:管理JDO事务
事务管理器实现:ansaction.jta.JtaTransactionManager
目标:使用一个JTA管理事务,在一个事务跨越多个资源时必须使用
(无须注入参数)
事务管理器实现:jb.PersistenceBrokerTransactionManager
目标:管理Apache的OJB事务
这些事务管理器的的父接口都是PlatformTransactionManager.Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager 代表事务管理接口(该接口定义了下面所说的三个方法),他并不知道底层如何管理事务,他只要求事务管理的实现类提供开始事务 (getTransaction())、提交事务(commit())、回滚事务(rollback()),但具体如何实现则交给具体的实现类完成——不 同的实现类代表不同的事务管理策略。
  说明:
  1、JTA事务管理器无须注入参数,是因为全局事务的JTA资源由JAVA EE服务器提供,而Spring容器能自行从JAVA EE服务器中获取该事务资源,所以无须使用依赖注入来配置。
  2、当使用JTA全局事务策略时,实际底层须应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:OC4JtaTransactionManager(
Oracle提供的应用服务器)、WebLogicJtaTransactionManager(Bea提供的WebLogic)、UowJtaTransactionManager(IBM提供的WebSphere)等
二、Spring编程式事务示例
步骤一、编写spring配置文件
下面实例使用DataSourceTransactionManager来管理JDBC事务。
查看Spring的配置信息:(l):
<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="/schema/beans"
    xmlns:xsi="/2001/XMLSchema-instance" xmlns:p="/schema/p"
    xsi:schemaLocation="http
:///schema/beans /schema/beans/spring-beans-2.5.xsd">
    <bean id="propertyConfig"
        class="org.springframework.fig.
  PropertyPlaceholderConfigurer">
        <property name="location">
            <value>connect.properties</value>
        </property>
    </bean>
    <bean id="dataSource" class="org.apachemons.dbcp.BasicDataSource">
        <property name="driverClassName">
            <value>${db.driver}</value>
        </property>
        <property name="url">
            <value>${db.url}</value>
        </property>
        <property name="username">
            <value>${db.username}</value>
        </property>
        <property name="password">
            <value>${db.password}</value>
        </property>
    </bean>
    <bean id="jdbcTemplate" class="org.JdbcTemplate">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
    <!-- JDBC事务管理器 注意:事务管理器传的参数是数据源-->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.
      DataSourceTransactionManager" scope="singleton">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
    <!-- 声明事务模板 -->
    <bean id="transactionTemplate"
        class="ansaction.support.
  TransactionTemplate">
        <property name="transactionManager">
            <ref bean="transactionManager" />
        </property>
    </bean>
    <bean id="bankDao" class="com.sunflower.dao.BankDaoImp">
        <property name="jdbcTemplate">
            <ref bean="jdbcTemplate" />
        </property>
        <property name="transactionTemplate">
            <ref bean="transactionTemplate" />
        </property>
    </bean>
 </beans>
上 面代码中配置了一个ansaction.support.TransactionTemplate实例,要 在代码中添加事务,Spring为我们提供了一种方法就是使用TransactionTemplate类。我们要为 TransactionTemplate装配一个TransactionManager,
如果是要配置Hibernate事务,要进行如下配置:(配置一个sessionFactory):
<!-- Hibernate事务管理器  注意:此事务管理器参数是sessionFactory-->
    <bean id="transactionManager"
  class="hibernate3.
  HibernateTransactionManager" scope="singleton">   
  <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
 如果是要配置JTA事务,要进行如下配置(无须参数):
 <bean id="transactionManager"
class="ansaction.jta.JtaTransactionManager" scope="singleton" >
  </bean>
 步骤二、使用TransactionTemplate进行事务管理:
package com.sunflower.dao;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import org.JdbcTemplate;
 import org.RowCallbackHandler;
 import ansaction.TransactionStatus;
 import ansaction.support.TransactionCallback;
 import ansaction.support.TransactionTemplate;
 import ity.People;
 public class BankDaoImp implements BankDao {
    private JdbcTemplate jdbcTemplate;
    private TransactionTemplate transactionTemplate;
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    public TransactionTemplate getTransactionTemplate() {
        return transactionTemplate;
    }
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        ansactionTemplate = transactionTemplate;
    }
    @Override
    public double getMoney(final People people) {
        double money = Money();
        // 开始事务,如果出现状况则回滚
        ute(new TransactionCallback<People>() {
            @Override
            public People doInTransaction(TransactionStatus ts) {
                try {
                    final People people2 = new People();spring ioc注解
                    // 使用JdbcTemplate进行持久化层操作
                    String sql = "select money from bank where name = ?";
                    Object[] params = new Object[] { Name() };
                    // 查询
                    jdbcTemplate.query(sql, params, new RowCallbackHandler() {
                        @Override
                        public void processRow(ResultSet rs)
                                throws SQLException {
                            people2.Double("money"));
                            System.out.Name() + "用户还有"

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。