博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Spring实战】—— 16 基于JDBC持久化的事务管理
阅读量:6001 次
发布时间:2019-06-20

本文共 5340 字,大约阅读时间需要 17 分钟。

前面讲解了基于JDBC驱动的Spring的持久化管理,本篇开始则着重介绍下与事务相关的操作。

通过本文你可以了解到:

  1 Spring 事务管理的机制

  2 基于JDBC持久化的事务管理

Spring的事务管理的机制

  Spring本身并不提供事务管理,它只是把事务管理提交给事务管理器,而事务管理器则有多种实现,常见的就是基于JDBC的、Hibernate的、JPA以及JTA的。

  操作流程可以参考下面的图片:

  其实还有好多种类的事务管理器,这里就不一一列举了。

基于JDBC持久化的事务管理

  基于JDBC的持久化,其实就是使用JDBC驱动,在利用spring模板的情况下实现的持久化。

  与Hibernate不同的是,它没有一些Session的概念以及实体关联关系等,因此在查询结果的时候,需要手动的进行转换。

  其他的方面来说,还是很简单实用的。

  下面看一下主要的代码实现流程:

  观察上面的实现结构,整个代码在DAO层的实现部分编写,其中包括主要的两个bean,一个是Spring的JDBC模板,一个是事务处理,这两个bean都会依赖于dataSource。

  DAO(data access object)数据访问对象,一般应用架构都会设计这样一层,用于存放于数据库进行交互的代码,以使应用层次化,便于管理和开发。

  因此就好理解下面的配置文件了:

  下面是dao的接口部分,仅仅给出了查询所有数据和插入一条数据的例子:

public interface NewJdbc {    //插入数据    public void insertPerson(String id,String name,int age);    //通过ID查询数据    public void findAllPersons();}

  下面是重要的部分,查询方法,仅仅通过模板提供了一个模板的使用样例。

  其中query方法含有两个参数。

  一个是查询SQL语句,另一个是转换类(用于把查询结果ResultSet转换成POJO类)。

 

  而插入数据的方法中,使用了事务管理。

  当执行new Integer("hello!")时,由于字符串无法转换到整型出错,会导致事务回滚,写操作回滚。

  其中的事务处理的源码参考如下,还没看明白,日后慢慢学习:

  源码给出,仅供参考:

public 
T execute(TransactionCallback
action) throws TransactionException { if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) { return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action); } else { TransactionStatus status = this.transactionManager.getTransaction(this); T result; try { result = action.doInTransaction(status); } catch (RuntimeException ex) { // Transactional code threw application exception -> rollback rollbackOnException(status, ex); throw ex; } catch (Error err) { // Transactional code threw error -> rollback rollbackOnException(status, err); throw err; } catch (Exception ex) { // Transactional code threw unexpected exception -> rollback rollbackOnException(status, ex); throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception"); } this.transactionManager.commit(status); return result; } }

  下面则是DAO的实现部分的所有代码:

public class NewJdbcImpl extends JdbcDaoSupport implements NewJdbc{    public DataSourceTransactionManager transactionManager;    public void setTransactionManager(DataSourceTransactionManager transactionManager) {        this.transactionManager = transactionManager;    }    /**     * 插入数据     */    public void insertPerson(final String id,final String name,final int age){        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);        final JdbcTemplate jdbcTemplate = this.getJdbcTemplate();        transactionTemplate.execute(new TransactionCallbackWithoutResult() {            protected void doInTransactionWithoutResult(TransactionStatus arg0) {                //这个方法内部,是一个事务                jdbcTemplate.update("insert into persons(id,name,age) values (?,?,?)",                         id,name,age);                new Integer("hello!");            }        });    }    /**     * 查询所有的数据     */    public void findAllPersons(){        List
list = this.getJdbcTemplate().query("select * from persons", new PersonRowMapper()); for(Person p : list){ System.out.println("id:"+p.getId()+" name:"+p.getName()+" age:"+p.getAge()); } } /** * 转换查询结果 * @author xingoo */ class PersonRowMapper implements RowMapper{ public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Person person = new Person(); person.setId(rs.getString(1)); person.setName(rs.getString(2)); person.setAge(rs.getInt(3)); return person; } }}

  Person的POJO类:

public class Person {    private String id;    private String name;    private int age;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

  测试时使用的main方法(一直没有使用单元测试,真不专业,习惯下次要改!)

public class test {    public static void main(String[] args) {        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");        NewJdbc newjdbc = (NewJdbc)ctx.getBean("newjdbcdao");        newjdbc.insertPerson("005", "xingoo5", 25);        newjdbc.findAllPersons();    }}

  数据库的SQL部分可以参考前一篇。

  【这里遗留了一个问题,当事务失败回滚时,查询语句也无法执行了。难道是因为使用的同一个JdbcTempalte的缘故?这个问题需要看源码探究,暂时记录一下。】

  1 根据网上搜索的资料:

  根据默认规则,如果在执行回调方法的过程中抛出了未检查异常,或者显式调用了TransacationStatus.setRollbackOnly() 方法,则回滚事务;如果事务执行完成或者抛出了 checked 类型的异常,则提交事务。

  但是回滚事务,为什么程序直接停止了呢。

  参考

  [1] 

  [2] 《Spring in Action》

本文转自博客园xingoo的博客,原文链接:,如需转载请自行联系原博主。
你可能感兴趣的文章
servlet总结
查看>>
2019.6/数据可视化方向面经
查看>>
菜鸟学步之石器时代 jsp MVC 数据操作
查看>>
event 事件 ctrlKey提交留言
查看>>
c++ primer 11
查看>>
第十九 django继续及CRM
查看>>
遇到一个注册表问题。(目标系统不支持长文件名)
查看>>
Spring 教程(四) Hello World 实例
查看>>
Windows最新本地提权exp视频
查看>>
终于解决改键的烦恼
查看>>
spring_ioc,DI
查看>>
9.Spring Boot实战之配置使用Logback进行日志记录
查看>>
web.xml中 error-page的正确用法
查看>>
JAVA_Thread_Runable
查看>>
空对象模式(Null Object Pattern)
查看>>
洛谷P3648 [APIO2014]序列分割(斜率优化)
查看>>
【传奇】话说JAVA和.NET的恩怨情仇……
查看>>
Windows下安装Redmine
查看>>
github相关
查看>>
1.部分(苹果)移动端的cookie不支持中文字符,2.从json字符串变为json对象时,只支持对象数组...
查看>>