spring ----编程式事务和声明式事务

一、 事务

事务管理对于企业应用而言是非常重要的,事务的存在保证了用户的每一次操作都是可靠的,当用户操作出现异常时也不至于破坏了后台的数据。例如银行的自动取款机,万一你在转账的时候出现了异常,事务机制会保证你后台的数据还是出异常操作之前的数据,也就是是你出异常的这些操作失效。

事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行,要么都不执行。

银行转账操作:开启事务,就是保证转账的操作要么都执行,要么都不执行。

如果在你的账户减去转账金额后出现异常,不能只是你的账户扣钱,对方账户加钱,这不就赔大了吗;如果此处出现异常,因为该事务的操作并没有全执行完,事务就会回退到转账操作前,也就是“自己账户减去 转账金额”的这个操作失效,不会执行了,这就保证了你账户的数据不被破坏,等系统好了你就可以再次执行转账操作了。

从上面的例子我们看出:事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保证用户和银行的利益都不受损失。

二、事务的四个关键属性(ACID)

原子性(atomicity):事务的原子性表现为一个事务所涉及到的多个操作是捆绑在一起的,要求事务中的所有操作要么都执行,要么都不执行,就像上面例子中的转账操作。

一致性(consistency):一个事务中不管涉及到多少个操作,都必须保证事务执行之前数据是正确的,事务执行之后数据也是正确,如果在事务执行过程中,存在操作失败的操作则其他所有操作都必须撤销,将数据恢复到事务执行之前的状态,这个过程叫“回滚”。

隔离性(isolation):要求多个事务在并发执行过程中不会互相干扰。在应用程序实际执行的过程中,事务往往是兵法执行的,所以很可能许多事务会同时处理相同的数据,因此每个事务都应该与其他事务分开执行,不然同一个数据同时在多个事务中都被修改,那这个数据不就乱了吗?

持久性(durability):持久性是事务执行完成后,他对数据的修改是永久保存的,不会因为时间长,或者出现故障而受影响。也就是说并不能你执行转账操作后过了一段时间后你转出去的金额自己又回到你的账户,也就想想吧。

三、JDBC中的事务:

当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
在JDBC中,事务默认是自动提交的,每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚
为了让多个 SQL 语句作为一个事务执行:
调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
在出现异常时,调用 rollback(); 方法回滚事务
可以通过Connection的getAutoCommit()方法来获得当前事务的提交方式

示例:银行转账的例子,要求张三给李四转1000元.

package cn.itcast.cd;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import cn.itcast.cd.utils.DbUtils;

public class TestTransaction {

    /*
     * 需求:张三给李四转账1000元
     *
     * 转账成功的条件:
     * 1、判断张三的账号余额是否>=1000
     * 2、从张三的账号中转出1000.
     * 3、给李四的账号中转入1000.
     */
    @Test
    public void testTrans(){
        Connection connection = DbUtils.getConnection();
        try {

            //开启事务,默认的情况下是true,  只要执行sql就开启事务物,执行完sql后就提交事务
            

connection.setAutoCommit(false);


            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            String sql = "";
            try {
                sql = "select * from accounts where name=?";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1, "张三");

                resultSet = preparedStatement.executeQuery();
                if (resultSet.next()){
                    Double sum = resultSet.getDouble("sum");

                    //判断余额
                    if (sum < 1000){
                        System.out.println("余额不足,操作失败!");
                        return;
                    }

                    //转出
                    sql = "update accounts set sum=sum-? where name=?";
                    preparedStatement = connection.prepareStatement(sql);
                    preparedStatement.setInt(1, 1000);
                    preparedStatement.setString(2, "张三");
                    preparedStatement.executeUpdate();

                    //创建异常,没有事务则转出了1000,发生异常,转入失败,整个转账操作失败!
                    int a = 2/0;

                    //转入
                    sql = "update accounts set sum=sum+? where name=?";
                    preparedStatement = connection.prepareStatement(sql);
                    preparedStatement.setInt(1, 1000);
                    preparedStatement.setString(2, "李四");
                    preparedStatement.executeUpdate();    

                    //提交事务,表明整个转账操作成功,将修改的数据更新到数据库中, 事务就又变成了自动提交.
                    connection.commit();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally{
                DbUtils.close(connection, preparedStatement, resultSet);
            }
        } catch (Exception e) {
            e.printStackTrace();

            //发生异常,事务回滚到原始状态.
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
    }
}

四、spring事务

主要有两种方式实现,一种是在代码中编写(编程式事务管理),一种是声明式事务(又可分为AOP式事务管理和注解式事务管理)。在代码中编写要更加细粒度,而很多时候我们只需要简单的事务处理,那就可以用声明式事务。

从图中可以看出,spring并不直接管理事务,而是提供了一个事务接口,实现事务的具体方法是由底层自己本身决定,如果管理JDBC DataSource事务就使用DataSourceTransactionManager事务管理器,如果管理Hibernate事务,则使用HibernateTransactionManager事务管理器;也就是说Spring管理机制是一种策略模式,他只提供接口,用哪种具体的事务管理器由持久层的实现框架决定。

五、编程式事务 :

编程式事务就是用编码的方式实现事务,比较类似于JDBC编程实现事务。

下面实例使用DataSourceTransactionManager来管理JDBC事务。

spring实现编程式事务的方式方式中提供了一种模板类,能够帮助我们实现DataSourceTransactionManager管理事务,这中模板类似于JDBCTemplate模板,将数据操作封装在模板类中。

实例:实现账号

1)创建数据库

2)配置好spring环境

<!-- 引入外部属性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置C3p0 -->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
    </bean>

    <!-- 配置业务层类 -->
    <bean id="accountService" class="com.neuedu.spring.demo1.AccountService">
        <property name="accountDao" ref="accountDao"></property>
        <!-- 注入事务管理的模板类 -->
        <property  name="atTemplate" ref="transactionTemplate"></property>
    </bean>
    <!-- 配置DAO类 -->
    <bean id="accountDao" class="com.neuedu.spring.demo1.AccountDaoImpl">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
    <!-- 配置事务管理的模板:spring为了简化事务管理代码提供的模板 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
    </bean>

3)DAO层实现类

package com.neuedu.spring.demo1;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:48:06
* @Description:实现转账DAO
* @parameter
*   */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

    /*Method:outMoney
     *Description:实现从数据库中将账户转账金额扣除
     *param:out,转账账户
     *param:money,转账金额
     */
    @Override
    public void outMoney(String out, Double money) {
        String sql="update t_account set salary=salary-? where name=?";
        this.getJdbcTemplate().update(sql, money,out);
    }
    /*Method:inMoney
     *Description:实现从数据库中向账户转入转账金额
     *param:in,收款账户
     *param:money,转账金额
     */
    @Override
    public void inMoney(String in, Double money) {
        String sql="update t_account set salary=salary+? where name=?";
        this.getJdbcTemplate().update(sql, money,in);
    }

}

4)业务层实现类

package com.neuedu.spring.demo1;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:39:04
* @Description:转账业务层实现
* @parameter
*   */
public class AccountService implements AccountServiceIn{
    //注入accountDao
    private AccountDaoImpl accountDao;
    public void setAccountDao(AccountDaoImpl accountDao) {
        this.accountDao = accountDao;
    }

    //注入事务管理的模板
    private TransactionTemplate atTemplate;

    public void setAtTemplate(TransactionTemplate atTemplate) {
        this.atTemplate = atTemplate;
    }
   /*Method:transfer
     *Description:实现转账操作
     *param:out ,转出账户
     *param:in,转入账户
     *param:money 转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
        atTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                //调用DAO层实现具体转账操作
                accountDao.outMoney(out, 200d);
                //人为制造Debug
                //int  i=10/0;
                accountDao.inMoney(in, 200d);
            }
        });

    }

}

测试:

@Test
    public void test() {
        ApplicationContext ioc=new ClassPathXmlApplicationContext("spring.xml");
        AccountService aService = ioc.getBean(AccountService.class);
        aService.transfer("孙悟空", "猪八戒", 200d);
    }

结果:

现在给转账操作人为制作bug,在测试一下事务是否正常。

程序抛出异常,执行失败

数据库数据不变

六、spring事务的概念

(一)基本原理:AOP

[1]前置通知:开启事务

[2]返回通知:提交事务

[3]异常通知:回滚事务

[4]后置通知:释放资源

(二)事务的传播行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。事务的传播行为可以由传播属性指定,在TransactionDefinition定义了7种类传播行为。

(三)事务的隔离级别

数据库事务并发存在的问题

假设现在有两个事务:Transaction01和Transaction02并发执行。

脏读

     [1]Transaction01将某条记录的AGE值从20修改为30。

     [2]Transaction02读取了Transaction01更新后的值:30。

     [3]Transaction01回滚,AGE值恢复到了20。

     [4]Transaction02读取到的30就是一个无效的值。

不可重复读

     [1]Transaction01读取了AGE值为20。

     [2]Transaction02将AGE值修改为30。

     [3]Transaction01再次读取AGE值为30,和第一次读取不一致。

幻读

     [1]Transaction01读取了STUDENT表中的一部分数据。

     [2]Transaction02向STUDENT表中插入了新的行。

     [3]Transaction01读取了STUDENT表时,多出了一些行。

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

TransactionDefinition 接口中定义了五个表示隔离级别的常量,其中DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是READ_COMMITTED。以下是其他四种的具体情况:

读未提交:READ UNCOMMITTED

      允许Transaction01读取Transaction02未提交的修改。

读已提交:READ COMMITTED

      要求Transaction01只能读取Transaction02已提交的修改。

可重复读:REPEATABLE READ

      确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。

串行化:SERIALIZABLE

      确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下

各个隔离级别解决并发问题的能力见下表

(四)事务超时

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。

默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

(五)事务只读属性

只读事务属性: 表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务。

七、声明式事务:

声明式事务是建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

方法一:基于注解的声明式事务(最简单)

1)数据库扔用上面的数据库;

2)配置spring

<!-- 配置业务层类 -->
    <bean id="accountService" class="com.neuedu.spring.demo2.AccountService">
        <property name="accountDao" ref="accountDao"></property>

    </bean>
    <!-- 配置DAO类 -->
    <bean id="accountDao" class="com.neuedu.spring.demo2.AccountDaoImpl">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
   

<!-- 配置事务管理器 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean><!-- 开启基于注解的事务管理 --> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>

3)DAO层不变

package com.neuedu.spring.demo2;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:48:06
* @Description:实现转账DAO
* @parameter
*   */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

    /*Method:outMoney
     *Description:实现从数据库中将账户转账金额扣除
     *param:out,转账账户
     *param:money,转账金额
     */
    @Override
    public void outMoney(String out, Double money) {
        String sql="update t_account set salary=salary-? where name=?";
        this.getJdbcTemplate().update(sql, money,out);
    }
    /*Method:inMoney
     *Description:实现从数据库中向账户转入转账金额
     *param:in,收款账户
     *param:money,转账金额
     */
    @Override
    public void inMoney(String in, Double money) {
        String sql="update t_account set salary=salary+? where name=?";
        this.getJdbcTemplate().update(sql, money,in);
    }

}

4)在业务层service类上加入注解

package com.neuedu.spring.demo2;

import org.springframework.transaction.annotation.Transactional;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:39:04
* @Description:转账业务层实现
* @parameter
*   */
@Transactional()
public class AccountService implements AccountServiceIn{
    //注入accountDao
    private AccountDaoImpl accountDao;
    public void setAccountDao(AccountDaoImpl accountDao) {
        this.accountDao = accountDao;
    }

   /*Method:transfer
     *Description:实现转账操作
     *param:out ,转出账户
     *param:in,转入账户
     *param:money 转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
                //调用DAO层实现具体转账操作
                accountDao.outMoney(out, 200d);
                //人为制造Debug
                //int  i=10/0;
                accountDao.inMoney(in, 200d);
    }

}

正常情况测试测试一下:

手动制造异常:

异常的执行结果:

因为刚才正常执行后悟空八戒分别是800,1200,接着执行异常情况,我并没有恢复数据库数据,执行结果是800,1200,说明因为异常没有再转账。

方法二:基于AspectJ的XML声明式事务:

基于AspectJ的XML声明式事务,实际就是AOP的XML实现方式。

spring配置:

<!-- 引入外部属性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置C3p0 -->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
    </bean>

    <!-- 配置业务层类 -->
    <bean id="accountService" class="com.neuedu.spring.demo3.AccountService">
        <property name="accountDao" ref="accountDao"></property>

    </bean>
    <!-- 配置DAO类 -->
    <bean id="accountDao" class="com.neuedu.spring.demo3.AccountDaoImpl">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
  

<!-- 配置事务管理器 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!-- 配置事务的通知,因为事务是建立在AOP上的 --> <tx:advice id="txAdivice" transaction-manager="dataSourceTransactionManager"> <tx:attributes> <!-- 配置事务管理的方法 --> <tx:method name="transfer" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置切面 --> <aop:config> <!-- 配置切入点表达式 --> <aop:pointcut expression="execution(* com.neuedu.spring.demo3.AccountService+.*(..))" id="pointcut"/> <!-- 配置切面 --> <aop:advisor advice-ref="txAdivice" pointcut-ref="pointcut"/> </aop:config>

然后DAO,Service都是业务正常的代码,里面没有关于事务的任何代码,显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污。

dao

package com.neuedu.spring.demo3;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:48:06
* @Description:实现转账DAO
* @parameter
*   */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

    /*Method:outMoney
     *Description:实现从数据库中将账户转账金额扣除
     *param:out,转账账户
     *param:money,转账金额
     */
    @Override
    public void outMoney(String out, Double money) {
        String sql="update t_account set salary=salary-? where name=?";
        this.getJdbcTemplate().update(sql, money,out);
    }
    /*Method:inMoney
     *Description:实现从数据库中向账户转入转账金额
     *param:in,收款账户
     *param:money,转账金额
     */
    @Override
    public void inMoney(String in, Double money) {
        String sql="update t_account set salary=salary+? where name=?";
        this.getJdbcTemplate().update(sql, money,in);
    }

}

service

package com.neuedu.spring.demo3;

import org.springframework.transaction.annotation.Transactional;

/*
* 项目名称:spring-BankAccount
* @author:wzc
* @date 创建时间:2017年9月12日 下午5:39:04
* @Description:转账业务层实现
* @parameter
*   */

public class AccountService implements AccountServiceIn{
    //注入accountDao
    private AccountDaoImpl accountDao;
    public void setAccountDao(AccountDaoImpl accountDao) {
        this.accountDao = accountDao;
    }

   /*Method:transfer
     *Description:实现转账操作
     *param:out ,转出账户
     *param:in,转入账户
     *param:money 转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
                //调用DAO层实现具体转账操作
                accountDao.outMoney(out, 200d);
                //人为制造Debug
                //int  i=10/0;
                accountDao.inMoney(in, 200d);
    }

}

而此时如何配置事务属性呢?在配置事务管理方法的时候可以添加事务的属性。

时间: 2024-11-08 18:58:45

spring ----编程式事务和声明式事务的相关文章

编程式导航和声明式导航

编程式导航和声明式导航 编程式跳转:用于在js中处理逻辑后需要页面进行跳转 vue的路由我们可以看做是一个数组,每次添加一个页面可以看成是向数组中push一个地址,当点击返回时就是向数组中的上一个值查找. 编程式跳转其实就是调用:this.$router.push( ) 在li 标签中加入点击函数@click="goDetail(item.id)" <!-- 编程式跳转 -->    <li class="proitem" v-for="

Spring的编程式事务和声明式事务

事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务管理,spring推荐使用TransactionTemplate. 声明式事务是建立在AOP之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法

一文解析Spring编程式和声明式事务实例讲解

接上一篇:一文解析Spring事务管理详解:通俗易懂,轻松掌握! Spring事务管理 Spring支持两种方式的事务管理: 编程式事务管理:?通过Transaction Template手动管理事务,实际应用中很少使用, 使用XML配置声明式事务:?推荐使用(代码侵入性最小),实际是通过AOP实现 实现声明式事务的四种方式: 基于 TransactionInterceptor 的声明式事务:?Spring 声明式事务的基础,通常也不建议使用这种方式,但是与前面一样,了解这种方式对理解 Spri

spring事物配置,声明式事务管理和基于@Transactional注解的使用

参考来源:http://blog.csdn.net/bao19901210/article/details/41724355 事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的一致性. spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务管理,spring推荐使用TransactionTemplate. 声明式事务管理建立在A

spring学习笔记(22)声明式事务配置,readOnly无效写无异常

在上一节内容中,我们使用了编程式方法来配置事务,这样的优点是我们对每个方法的控制性很强,比如我需要用到什么事务,在什么位置如果出现异常需要回滚等,可以进行非常细粒度的配置.但在实际开发中,我们可能并不需要这样细粒度的配置.另一方面,如果我们的项目很大,service层方法很多,单独为每个方法配置事务也是一件很繁琐的事情.而且也可能会造成大量重复代码的冗杂堆积.面对这些缺点,我们首要想到的就是我们spring中的AOP了.spring声明式事务的实现恰建立在AOP之上. 在这一篇文章中,我们介绍s

【Spring】Spring使用XML配置声明式事务

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.事务介绍 事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用. 事务的四个关键属性(ACID) ① 原子性(atomicity):事务室一个原子操作,有一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用② 一致性(consistency):一旦所

spring编程式事务

先看一下配置文件(简单配置) <pre name="code" class="html"><!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverC

阶段3 2.Spring_10.Spring中事务控制_9 spring编程式事务控制1-了解

编程式的事物控制,使用的情况非常少,主要作为了解 新建项目 首先导入包坐标 复制代码 这里默认值配置了Service.dao和连接池其他的内容都没有配置 也就说现在是没有事物支持的.运行测试文件 有错误,但是金额还是被减去了 编码的方式加事务控制 事务控制都离不开提交和回滚这两个操作.在spring里面它吧提交和回滚的方法提交到事务管理器里面了. 于是我们无论如何都需要在bean.xml里面配置事务管理器 接下来要进行事务控制,那肯定需要提交和回滚的操作 spring提交了一个对象,叫做事务模板

spring的学习____12 声明式事务(AoP的横向织入)

1.事务的介绍: 事务涉及到数据的一致性问题. 事务:要么都成功,要么都不成功! 事务的四大特性: ACID :原子性:一致性:隔离性:持久性. 编程中遇到的实际问题: 在如下的实现类(UserDaoImpl)中,执行了:先添加一个user,再删除一个user的操作,最后打印出所有的用户列表. 当我们人为的在删除代码写错时(即就不能成功执行删除操作),发现程序还是执行了添加和打印用户列表的其余两步,这就不符合事物的一致性. public class UserDaoImpl implements