栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring 事务的简单用法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring 事务的简单用法

Spring的事务管理不需要与任何特定的事务API耦合。对不同的持久层访问技术,编程式事务提供了一致的事务编程风格,通过模板化操作一致性地管理事务。

Spring 支持的事务策略

Spring具体的事务管理由PlatformTransactionManager的不同实现类来完成。在Spring 容器中配置PlatfonnTransactionManager Bean 时,必须针对不同的环境提供不同的实现类。

使用Spring JDBC辅助类增删改查一个简单表的数据

创建一个StudentDao接口,并添加增删改查的操作:

package com.bnuz.dao;

public interface StudentDao {

    public void insert(String studentNo, String studentName, String studentSchool);

    public void delete(String studentNo);

    public void updateStudentName(String studentNo, String studentName, String studentSchool);

    public void findByNo(String studentNo);

}

创建StudentDaoImpl类并实现StudentDao接口:

package com.bnuz.dao.impl;

import com.bnuz.dao.StudentDao;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.util.List;

public class StudentDaoImpl implements StudentDao {

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource){
        this.dataSource = dataSource;
    }

    @Override
    public void insert(String studentNo, String studentName, String studentSchool) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.update("insert into t_student values (?,?,?)", studentNo, studentName, studentSchool);
    }

    @Override
    public void delete(String studentNo) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "delete from t_student where id=" + studentNo;
        int result = jdbcTemplate.update(sql);
        System.out.println("成功删除" + result + "条记录");
    }

    @Override
    public void updateStudentName(String studentNo, String studentName, String studentSchool) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "update t_student set name=?,school=? where id=?";
        int result = jdbcTemplate.update(sql, studentName, studentSchool, studentNo);
        System.out.println("成功更新" + result + "条记录");
    }

    @Override
    public void findByNo(String studentNo) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select * from t_student where id=" + studentNo;
        List row = jdbcTemplate.queryForList(sql);
        System.out.println("查询结果:" + row );
    }


}

spring-config.xml配置文件如下: 



    
    

    

    

配置JDBC 数据源的局部事务管理器时,使用DataSourceTransactionManager类,该类实现了PlatformTransactionManager接口,是针对采用数据源连接的特定实现的,配置DataSourceTransactionManager时需要依赖注入DataSource的引用。

在main函数编写增删改查的代码,实验结果如下:

调用insert方法:

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
StudentDao dao = (StudentDao)ctx.getBean("studentDao" , StudentDao.class);
dao.insert("1901030086", "默辰", "北师珠");

 调用delete方法:

dao.delete("1901030086");

 

 调用updateStudentName方法:

dao.updateStudentName("1901030086", "默辰_lyq", "北理工" );

  调用findByNo方法:

dao.findByNo("1901030086");

使用XML Schema 配置事务策略

Spring同时支持编程式事务策略和声明式事务策略,通常都推荐采用声明式事务策略。

Spring的XML Schema方式提供了tx:命名空间来配置事务管理,tx:命名空间下提供了元素来配置事务增强处理,一旦使用该元素配置了事务增强处理,就可直接使用元素启用自动代理了。

 配置,元素时除了需要transaction-manager属性(该属性的默认值是"transactionManager")指定事务管理器之外,还需要配置一个子元素,该子元素里又可包含多个子元素。元素的属性、子元素的关系如图所示:

从图可以看出,配置元素的重点就是配置子元素,实际上每个子元素都为一批方法指定了所需的事务定义,包括事务传播属性、事务隔离属性、事务超时属性、只读事务、对指定异常回滚、对指定异常不回滚等。

配置子元素可以指定如下几个属性:
name:必选属性,与该事务语义关联的方法名。该属性支持使用通配符,例如'get*'、'handle*'、'on*Event'等。
propagation:指定事务传播行为,该属性值可为Propagation 枚举类的任一枚举值,各枚举值的含义下面立即介绍。该属性的默认值为Propagation.REQUIRED。
isolation:指定事务隔离级别,该属性值可为Isolation 枚举类的任一枚举值,各枚举值的具体含义可参考API 文挡。该属性的默认值为Isolation.DEFAULT。
timeout:指定事务超时的时间(以秒为单位),指定-1意味着不超时,该属性的默认值是- 1。
read- only:指定事务是否只读。该属性的默认值是false 。
rollback-for:指定触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类, 多个异常类之间以英文逗号隔开。
no-rollback-for:指定不触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类,多个异常类之间以英文逗号隔开。 

子元素的propagation属性用于指定事务传播行为,Spring 支持的事务传播行为如下:
PROPAGATION_MANDATORY:要求调用该方法的线程必须处于事务环境中,否则抛出异常。
PROPAGATION_NESTED:即使执行该方法的线程己处于事务环境中,也依然启动新的事务,方法在嵌套的事务里执行;即使执行该方法的线程并未处于事务环境中,也启动新的事务,然后执行该方法, 此时与PROPAGATION_REQUIRED相同。
PROPAGATION_NEVER:不允许调用该方法的线程处于事务环境中,如果调用该方法的线程处于事务环境中,则抛出异常。
PROPAGATION_NOT_SUPPORTED:如果调用该方法的线程处于事务环境中,则先暂停当前事务,然后执行该方法。
PROPAGATION_REQUIRED:要求在事务环境中执行该方法,如果当前执行线程己处于事务环境中,则直接调用;如果当前执行线程不处于事务环境中, 则启动新的事务后执行该方法。
PROPAGATION_REQUIRES_NEW:该方法要求在新的事务环境中执行,如果当前执行线程己处于事务环境中,则先暂停当前事务,启动新事务后执行该方法:如果当前调用线程不处于事务环境中,则启动新的事务后执行方法。
PROPAGATION_SUPPORTS:如果当前执行线程处于事务环境中,则使用当前事务,否则不便用事务。 

下面是spring-config.xml完整配置:




    

    

    

    
        

            
            
        
    

    
    
    
        
        
        
        
    

的定义,确保由txAdvice切面定义的事务增强处理能在合适的切入点被织入,实际上是由Spring 提供的Bean 后处理器完成的。

修改insert方法如下,并运行该方法:

@Override
    public void insert(String studentNo, String studentName, String studentSchool) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.update("insert into t_student values (?,?,?)", studentNo, studentName, studentSchool);
        jdbcTemplate.update("insert into t_student values (?,?,?)", studentNo, studentName, studentSchool);
    }

数据库也没有插入相对应的数据:

运行结果出现一个异常,而且insert()方法所执行的两条SQL 语句全部回滚一一因为事务控制的缘故。如果没有事务控制,则第一条记录可以被插入。

当使用为目标Bean生成事务代理之后,SpringAOP 将会把负责事务操作的增强处理织入目标Bean的业务方法中。在这种情况下,事务代理的业务方法将如图所示:

通过使用rollback-for属性可强制Spring遇到特定checked异常时自动回滚事务,下面的XML 配置片段示范了这种用法:

如果想让Spring遇到特定runtime异常时强制不回滚事务,则可通过no-rollback-for属性来指定,如下面的配置片段所示:

使用@Transactional

Spring 还允许将事务配置放在Java 类中定义,这需要借助于@Transactional注解,该注解既可用于修饰Spring Bean 类,也可用于修饰Bean 类中的某个方法。
如果使用@Transactional修饰Bean 类,则表明这些事务设置对整个Bean 类起作用;如果使用@Transactional 修饰Bean类的某个方法,则表明这些事务设置只对该方法有效。
使用@Transactional时可指定如下属性:
isolation:用于指定事务的隔离级别。默认为底层事务的隔离级别。
noRollbackFor:指定遇到特定异常时强制不回滚事务。
noRollbackForClassName:指定遇到特定的多个异常时强制不回滚事务。该属性值可以指定多个异常类名。
propagation:指定事务传播行为。
readOnly:指定事务是否只读。
rollbackFor: 指定遇到特定异常时强制回滚事务。
rollbackForClassName:指定遇到特定的多个异常时强制回滚事务。该属性值可以指定多个异常类名。
timeout:指定事务的超时时长。
根据上面的解释不难看出,其实该注解所指定的属性与元素中所指定的事务属性基本上是对应的,它们的意义也基本相似。 

仅使用这个注解修饰还不够,还需要让Spring 根据注f怦来配置事务代理,所以还需要在Spring 配置文件中增加如下配置片段:

使用Spring中定时调度功能

实现定时(每3秒钟)调用一个方法。

新建CronTriggerActionBean类:

package com.bnuz;

public class CronTriggerActionBean {
    public void display(){
        System.out.println("定时打印");
    }
}

spring-config.xml部分配置如下:



    

    
        
            
        
        
            0/3
        
    

    
        
            
                
            
        
    

 

这里的报错目前找不到原因,上面的理论中的运行结果。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781717.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号