• 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】


    一、JDBC编程特点

      静态代码+动态变量=JDBC编程。

      静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口。

      动态变量:用户名、密码、连接的数据库、表名、SQL语句等信息。

      在spring中动态变量能够通过注入的形式给予。这样的变成方式适合包装成模板。静态代码构成了模板,而动态变量是需要传入的参数。

    二、核心类JdbcTemplate

      1.基于模板的设置。

      2.完成了资源的创建和释放的工作。

      3.简化了我们的JDBC操作。

      4.完成了对JDBC的核心流程的工作,包括SQL语句的创建和执行。

      5.仅仅需要传递DataSource就可以将其实例化。

      6.JdbcTemplate只需要创建一次。

      7.JdbcTemplate是线程安全类。

    三、使用三种方式将DataSource对象传递给JdbcTemplate,创建JdbcTemplate对象。

      1.第一种方法:继承org.springframework.jdbc.core.support.JdbcDaoSupport类

        (1)首先配置数据源DataSource,这里使用c3p0数据库连接池

    1 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    2         <constructor-arg index="0" value="namedconfig"></constructor-arg>
    3 </bean>
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <c3p0-config>
     3     <!-- 默认配置,只可以出现一次 -->
     4     <default-config>
     5         <!-- 连接超时设置30秒 -->
     6         <property name="checkoutTimeout">30000</property>
     7         <!-- 30秒检查一次connection的空闲 -->
     8         <property name="idleConnectionTestPeriod">30</property>
     9         <!--初始化的池大小 -->
    10         <property name="initialPoolSize">2</property>
    11         <!-- 最多的一个connection空闲时间 -->
    12         <property name="maxIdleTime">30</property>
    13         <!-- 最多可以有多少个连接connection -->
    14         <property name="maxPoolSize">10</property>
    15         <!-- 最少的池中有几个连接 -->
    16         <property name="minPoolSize">2</property>
    17         <!-- 批处理的语句-->
    18         <property name="maxStatements">50</property>
    19         <!-- 每次增长几个连接 -->
    20         <property name="acquireIncrement">3</property>
    21         <property name="driverClass">com.mysql.jdbc.Driver</property>
    22         <property name="jdbcUrl">
    23             <![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
    24         </property>
    25         <property name="user">root</property>
    26         <property name="password">5a6f38</property>
    27     </default-config> 
    28     
    29     <named-config name="namedconfig">
    30         <!-- 连接超时设置30秒 -->
    31         <property name="checkoutTimeout">30000</property>
    32         <!-- 30秒检查一次connection的空闲 -->
    33         <property name="idleConnectionTestPeriod">30</property>
    34         <!--初始化的池大小 -->
    35         <property name="initialPoolSize">2</property>
    36         <!-- 最多的一个connection空闲时间 -->
    37         <property name="maxIdleTime">30</property>
    38         <!-- 最多可以有多少个连接connection -->
    39         <property name="maxPoolSize">2</property>
    40         <!-- 最少的池中有几个连接 -->
    41         <property name="minPoolSize">2</property>
    42         <!-- 批处理的语句-->
    43         <property name="maxStatements">50</property>
    44         <!-- 每次增长几个连接 -->
    45         <property name="acquireIncrement">2</property>
    46         <property name="driverClass">com.mysql.jdbc.Driver</property>
    47         <property name="jdbcUrl">
    48             <![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
    49         </property>
    50         <property name="user">root</property>
    51         <property name="password">5a6f38</property>
    52     </named-config> 
    53 </c3p0-config>
    c3p0-config.xml

        (2)定义Dao

    1 package com.kdyzm.spring.jdbc;
    2 
    3 public interface CourseDao {
    4     public Course getCourse(Long cid);
    5 }
    com.kdyzm.spring.jdbc.CourseDao

        (3)实现Dao,这是非常关键的一步,因为需要继承JdbcDaoSupport类。

     1 package com.kdyzm.spring.jdbc;
     2 
     3 import java.sql.SQLException;
     4 
     5 import org.apache.commons.dbutils.QueryRunner;
     6 import org.apache.commons.dbutils.handlers.BeanHandler;
     7 import org.springframework.jdbc.core.support.JdbcDaoSupport;
     8 
     9 public class CourseDaoImpl extends JdbcDaoSupport implements CourseDao{
    10     @Override
    11     public Course getCourse(Long cid) {
    12         String sql="select cid,cname from course where cid = ?";
    13         QueryRunner run=new QueryRunner(this.getDataSource());
    14         Course course=null;
    15         try {
    16             course = run.query(sql,new BeanHandler<Course>(Course.class),1L);
    17         } catch (SQLException e) {
    18             e.printStackTrace();
    19         }
    20         return course;
    21     }
    22 }

        (4)在applicationContext.xml文件中进行配置,注意这里使用proerty标签相当于调用了JdbcDaoSupport的setDataSource方法。

    <!-- 第一种方法:继承JdbcDaoSupport -->
        <bean id="courseDao" class="com.kdyzm.spring.jdbc.CourseDaoImpl">
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>
        </bean>

        (5)测试代码:

    1 ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/jdbc/applicationContext.xml");
    2 CourseDao courseDao = (CourseDao) context.getBean("courseDao");
    3 Course course=courseDao.getCourse(1L);
    4 System.out.println(course);
     1 package com.kdyzm.spring.jdbc;
     2 /*
     3  * 课程类
     4  */
     5 public class Course {
     6     private Long cid;
     7     private String cname;
     8     
     9     public Course() {
    10     }
    11     @Override
    12     public String toString() {
    13         return "Course [cid=" + cid + ", cname=" + cname + "]";
    14     }
    15     public Long getCid() {
    16         return cid;
    17     }
    18     public void setCid(Long cid) {
    19         this.cid = cid;
    20     }
    21     public String getCname() {
    22         return cname;
    23     }
    24     public void setCname(String cname) {
    25         this.cname = cname;
    26     }
    27 }
    com.kdyzm.spring.jdbc.Course

          测试结果:

          

        分析:继承了JdbcDaoSupport类为什么是关键?JdbcDaoSupport类中有一个非常关键的方法setDataSource,它有一个JdbcTemplate类型的成员变量,我们通过使用该成员变量来完成所有工作:

          

        通过上面的流程图可以看到实际上JdbcDaoSupport将DataSource的引用传递给了JdbcTemplate,JdbcTemplate对象使用该DataSource对象完成对数据库的增删查改操作。

      2.第二种方法:使用JdbcTemplate对象作为成员变量

        (1)配置数据源

    <!-- 引入DataSource -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <constructor-arg index="0" value="namedconfig"></constructor-arg>
        </bean>

        (2)创建CourseDaoImpl1类,该类不再继承JdbcDaoSupport类,只是实现了CourseDao接口,但是新增加了成员变量JdbcTemplate jdbcTemplate,并提供了set、get方法。

     1 package com.kdyzm.spring.jdbc;
     2 /*
     3  * 第二种实现方式:使用JdbcTemplate类作为成员变量
     4  */
     5 import java.sql.SQLException;
     6 
     7 import org.apache.commons.dbutils.QueryRunner;
     8 import org.apache.commons.dbutils.handlers.BeanHandler;
     9 import org.springframework.jdbc.core.JdbcTemplate;
    10 
    11 public class CourseDaoImpl1 implements CourseDao{
    12 
    13     JdbcTemplate jdbcTemplate=null;
    14     
    15     public JdbcTemplate getJdbcTemplate() {
    16         return jdbcTemplate;
    17     }
    18 
    19     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    20         this.jdbcTemplate = jdbcTemplate;
    21     }
    22 
    23     public Course getCourse(Long cid) {
    24         String sql="select cid,cname from course where cid = ?";
    25         QueryRunner run=new QueryRunner(this.getJdbcTemplate().getDataSource());
    26         Course course=null;
    27         try {
    28             course = run.query(sql,new BeanHandler<Course>(Course.class),cid);
    29         } catch (SQLException e) {
    30             e.printStackTrace();
    31         }
    32         return course;
    33     }
    34 }

        (3)配置applicationContext.xml文件

            * 将JdbcTemplate对象纳入Spring容器管理

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <constructor-arg index="0">
                <ref bean="dataSource"/>
            </constructor-arg>
        </bean>

            * 将courseDao1纳入Spring容器管理

    <bean id="courseDao1" class="com.kdyzm.spring.jdbc.CourseDaoImpl1">
            <property name="jdbcTemplate">
                <ref bean="jdbcTemplate"/>
            </property>
    </bean>

          原理分析:实际上JdbcDaoSupport类的核心就是JdbcTemplate,同理,我们也可以将该类对象作为成员变量,效果是相同的。

      3.第三种方式:继承JdbcTemplate类。

        (1)配置数据源,同上

        (2)新建CourseDaoImpl2,该类继承了JdbcTemplate类,并且实现了CourseDao接口。

     1 package com.kdyzm.spring.jdbc;
     2 /*
     3  * 第二种实现方式:使用JdbcTemplate类作为成员变量
     4  */
     5 import java.sql.SQLException;
     6 
     7 import javax.sql.DataSource;
     8 
     9 import org.apache.commons.dbutils.QueryRunner;
    10 import org.apache.commons.dbutils.handlers.BeanHandler;
    11 import org.springframework.jdbc.core.JdbcTemplate;
    12 
    13 public class CourseDaoImpl2 extends JdbcTemplate implements CourseDao{
    14     public CourseDaoImpl2(DataSource dataSource) {
    15         super(dataSource);
    16     }
    17 
    18     public Course getCourse(Long cid) {
    19         String sql="select cid,cname from course where cid = ?";
    20         QueryRunner run=new QueryRunner(this.getDataSource());
    21         Course course=null;
    22         try {
    23             course = run.query(sql,new BeanHandler<Course>(Course.class),cid);
    24         } catch (SQLException e) {
    25             e.printStackTrace();
    26         }
    27         return course;
    28     }
    29 }

        (3)配置applicationContext.xml文件

    <!-- 第三种方法:继承JdbcTemplate类 -->
        <bean id="courseDao2" class="com.kdyzm.spring.jdbc.CourseDaoImpl2">
            <constructor-arg index="0">
                <ref bean="dataSource"/>
            </constructor-arg>
        </bean>

        测试略。原理分析:最根本的就是JdbcTemplate类,所以干脆继承该类。

    四、spring中的事务管理

      1.Spring的事务管理是声明式的事务管理。什么是"声明式"的事务管理?在配置文件中声明某个方法需要开启事务进行管理,然后被声明的这个方法就会开启事务。

        Spring事务管理相对于Hibernate和JDBC的优越之处:

          

      2.Spring的事务管理器

        spring没有直接管理事务,而是将管理事务的责任委托给JTA或者相应的持久性机制所提供的某个特定平台的事务实现。

    事务管理器

    目标

    org.springframework.transaction.PlatformTransactionManager

    事务管理器的顶级接口

    org.springframework.transaction.support.AbstractPlatformTransactionManager

    事务管理器的超类

    org.springframework.jdbc.datasource.DataSourceTransactionManager

    在单一的JDBC DataSource中的事务管理

    org.springframework.orm.hibernate3.HibernateTransactionManager

    当持久化机制是hibernate的时候,使用它来管理事务

    org.springframework.orm.jdo.JdoTransactionManager

    使用一个JTA实现来管理事务,当一个事务跨越多个资源的时候必须使用

      3.Spring事务的传播属性

        

          在实际工作当中,99%的使用过的是REQUIRED。

      4.spring事务的隔离级别

        

          在实际工作中,99%使用的是DEFAULT。

      5.XML配置练习

        (1)引入命名空间

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:aop="http://www.springframework.org/schema/aop"
     6    xmlns:tx="http://www.springframework.org/schema/tx"
     7     
     8     xsi:schemaLocation="
     9            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    10            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    11            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    12          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    13            ">
    14     
    15 </beans>

         (2)user表:

    CREATE TABLE `user` (
       `id` varchar(32) NOT NULL,
       `name` varchar(32) DEFAULT NULL,
       `age` int(11) DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8

        (3)新建类:

     1 package com.kdyzm.spring.jdbc.transaction1;
     2 
     3 public class User {
     4     private String id;
     5     private String name;
     6     private Integer age;
     7     public User() {
     8     }
     9     public String getId() {
    10         return id;
    11     }
    12     public void setId(String id) {
    13         this.id = id;
    14     }
    15     public String getName() {
    16         return name;
    17     }
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21     public Integer getAge() {
    22         return age;
    23     }
    24     public void setAge(Integer age) {
    25         this.age = age;
    26     }
    27     @Override
    28     public String toString() {
    29         return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
    30     }
    31 }
    com.kdyzm.spring.jdbc.transaction1.User
    1 package com.kdyzm.spring.jdbc.transaction1;
    2 
    3 import java.sql.SQLException;
    4 
    5 public interface UserDao {
    6     public User updateUser(User user) throws SQLException;
    7 }
    com.kdyzm.spring.jdbc.transaction1.UserDao

    非常重要的一个类:com.kdyzm.spring.jdbc.transaction1.UserDaoImpl

     1 package com.kdyzm.spring.jdbc.transaction1;
     2 
     3 import java.sql.SQLException;
     4 
     5 import org.apache.commons.dbutils.QueryRunner;
     6 import org.springframework.jdbc.core.JdbcTemplate;
     7 
     8 public class UserDaoImpl implements UserDao{
     9     private JdbcTemplate jdbcTemplate;
    10 
    11     public JdbcTemplate getJdbcTemplate() {
    12         return jdbcTemplate;
    13     }
    14 
    15     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    16         this.jdbcTemplate = jdbcTemplate;
    17     }
    18     
    19     /**
    20      * 使用该方法测试非跨dao事务回滚问题
    21      * 一定不能使用dbutils工具,否则不能回滚!!!!!!!!!!!!!
    22      * @throws SQLException 
    23      */
    24     @Override
    25     public User updateUser(User user) throws SQLException {
    26         String sql="update user set age=age+1 where id='0001'";
    27 //        QueryRunner runner=new QueryRunner(this.jdbcTemplate.getDataSource());
    28 //        runner.update(this.jdbcTemplate.getDataSource().getConnection(),sql,"0001");
    29         this.jdbcTemplate.execute(sql);
    30         int a=1/0;
    31         sql="update user set age=age+1 where id='0002'";
    32         this.jdbcTemplate.execute(sql);
    33 //        runner.update(this.jdbcTemplate.getDataSource().getConnection(),sql,"0002");
    34         return null;
    35     }
    36 }

        使用该类应当注意:不能使用dbutils处理事务相关的问题,否则不能回滚!!

    1 package com.kdyzm.spring.jdbc.transaction1;
    2 
    3 import java.sql.SQLException;
    4 
    5 public interface UserService {
    6     public User updateUser(User user) throws SQLException;
    7 }
    com.kdyzm.spring.jdbc.transaction1.UserService
     1 package com.kdyzm.spring.jdbc.transaction1;
     2 
     3 import java.sql.SQLException;
     4 
     5 
     6 public class UserServiceImpl implements UserService{
     7     private UserDao userDao;
     8     public UserDao getUserDao() {
     9         return userDao;
    10     }
    11 
    12     public void setUserDao(UserDao userDao) {
    13         this.userDao = userDao;
    14     }
    15 
    16     @Override
    17     public User updateUser(User user) throws SQLException {
    18         return userDao.updateUser(user);
    19     }
    20 
    21 }
    com.kdyzm.spring.jdbc.transaction1.UserServiceImpl

      使用的数据库连接池:c3p0,配置文件如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <c3p0-config>
     3     <!-- 默认配置,只可以出现一次 -->
     4     <default-config>
     5         <!-- 连接超时设置30秒 -->
     6         <property name="checkoutTimeout">30000</property>
     7         <!-- 30秒检查一次connection的空闲 -->
     8         <property name="idleConnectionTestPeriod">30</property>
     9         <!--初始化的池大小 -->
    10         <property name="initialPoolSize">2</property>
    11         <!-- 最多的一个connection空闲时间 -->
    12         <property name="maxIdleTime">30</property>
    13         <!-- 最多可以有多少个连接connection -->
    14         <property name="maxPoolSize">10</property>
    15         <!-- 最少的池中有几个连接 -->
    16         <property name="minPoolSize">2</property>
    17         <!-- 批处理的语句-->
    18         <property name="maxStatements">50</property>
    19         <!-- 每次增长几个连接 -->
    20         <property name="acquireIncrement">3</property>
    21         <property name="driverClass">com.mysql.jdbc.Driver</property>
    22         <property name="jdbcUrl">
    23             <![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
    24         </property>
    25         <property name="user">root</property>
    26         <property name="password">5a6f38</property>
    27     </default-config> 
    28     
    29     <named-config name="namedconfig">
    30         <!-- 连接超时设置30秒 -->
    31         <property name="checkoutTimeout">30000</property>
    32         <!-- 30秒检查一次connection的空闲 -->
    33         <property name="idleConnectionTestPeriod">30</property>
    34         <!--初始化的池大小 -->
    35         <property name="initialPoolSize">2</property>
    36         <!-- 最多的一个connection空闲时间 -->
    37         <property name="maxIdleTime">30</property>
    38         <!-- 最多可以有多少个连接connection -->
    39         <property name="maxPoolSize">2</property>
    40         <!-- 最少的池中有几个连接 -->
    41         <property name="minPoolSize">2</property>
    42         <!-- 批处理的语句-->
    43         <property name="maxStatements">50</property>
    44         <!-- 每次增长几个连接 -->
    45         <property name="acquireIncrement">2</property>
    46         <property name="driverClass">com.mysql.jdbc.Driver</property>
    47         <property name="jdbcUrl">
    48             <![CDATA[jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8]]>
    49         </property>
    50         <property name="user">root</property>
    51         <property name="password">5a6f38</property>
    52     </named-config> 
    53 </c3p0-config>
    c3p0-config.xml

      最后,最重要的com.kdyzm.spring.jdbc.transaction1.applicationContext.xml文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:aop="http://www.springframework.org/schema/aop"
     6     xmlns:tx="http://www.springframework.org/schema/tx"
     7     xsi:schemaLocation="
     8            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     9            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    10            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    11            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    12            ">
    13     <!-- 首先配置数据源 -->
    14     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    15         <constructor-arg index="0" value="namedconfig"></constructor-arg>
    16     </bean>
    17     <!-- 配置JdbcTemplate模板 -->
    18     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    19         <constructor-arg index="0">
    20             <ref bean="dataSource"/>
    21         </constructor-arg>
    22     </bean>
    23     <!-- 配置JDBC事务管理器 -->
    24     <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    25         <property name="dataSource">
    26             <ref bean="dataSource"/>
    27         </property>
    28     </bean>
    29     
    30     
    31     <!-- 配置通知 -->
    32     <tx:advice id="advice" transaction-manager="dataSourceTransactionManager">
    33         <tx:attributes >
    34             <tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
    35         </tx:attributes>
    36     </tx:advice>
    37     
    38     <!-- 配置切入点 -->
    39     <aop:config>
    40         <!-- <aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction.*ServiceImpl.*(..))" id="perform"/> -->
    41         <aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction1.UserServiceImpl.updateUser(..))" id="perform"/>
    42         <aop:advisor advice-ref="advice" pointcut-ref="perform"/>
    43     </aop:config>
    44     
    45     <!-- 需要注意的是不需要配置切面,因为如果要配置切面的话就需要程序员完成(事务管理),
    46         这样spring就没有意义了 -->
    47         
    48     <!-- 程序员需要干的事情! -->
    49     <!-- 需要纳入spring容器的 -->
    50     <bean id="userDao" class="com.kdyzm.spring.jdbc.transaction1.UserDaoImpl">
    51         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    52     </bean>
    53     <bean id="userService" class="com.kdyzm.spring.jdbc.transaction1.UserServiceImpl">
    54         <property name="userDao" ref="userDao"></property>
    55     </bean>
    56 </beans>

      (4)测试

    ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/jdbc/transaction1/applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            User user=new User();
            userService.updateUser(user);

        由于在UserDaoImpl.updateUser方法中存在/0的异常,所以方法会异常终止,但是spring会回滚方法中的事务。通过查看数据库中user的age字段可以得到结果。如果0001和0002并没有发生任何改变,则表示成功回滚;如果只有0001字段发生了自增长,则表示回滚失败。

      6.小练习总结:

        (1)事务的方法中不能使用dbutils工具,否则回滚失败!

        (2)在service层控制事务,目标类是*ServiceImpl,目标方法是update方法。所以配置切入点表达式是:

            <aop:pointcut expression="execution(* com.kdyzm.spring.jdbc.transaction1.UserServiceImpl.updateUser(..))" id="perform"/>

        (3)事务管理器是Jdbc事务管理器,所以使用的类是DataSourceTransactionManager,创建对象的时候需要调用setDataSource方法传入DataSource参数。

    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>
    </bean>

        (4)配置通知,需要制定事务管理器,这里的配置是一个模板,并不针对某个类中的方法,而是针对匹配到的所有方法:

    <tx:advice id="advice" transaction-manager="dataSourceTransactionManager">
            <tx:attributes >
                <tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
                <tx:method name="*" read-only="true" isolation="DEFAULT" propagation="REQUIRED"/>
            </tx:attributes>
    </tx:advice>

          * isolation:制定事务的隔离界别,使用default表示使用数据库制定的隔离级别,spring不再另外指定。

          * propagation:指定事务的传播属性,默认是REQUIRED,表示如果当前方法已经在一个事务中运行则加入该事务,否则创建一个新事务。

     

     

      

     

     

     

     

     

     

     

     

     

     

     

     

          

     

  • 相关阅读:
    Debian vim没有颜色的解决办法
    第四次作业
    第三次作业
    第二次作业
    Mad Libs游戏 & 华氏温度与摄氏温度转换
    有趣故事
    Mybatis的使用及增删改查
    jdbc数据连接池
    详解MySQL数据类型
    SQL语法大全
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4852786.html
Copyright © 2020-2023  润新知