文章导读:

本文主要讲解了如何在没有框架情况下如何解决Dao的事务问题, 重点理解Connection存放到WeakReference中为什么垃圾回收的时候Connection不回收

视频与源码下载:http://edu.51cto.com/lecturer/index/user_id-9166337.html  (代码在视频的附件中)

先准备下测试的环境:db.sql、model、dao、Service

db.sql 代码如下(只有一张表)

 /*删除商城数据库,如果存在*/
drop database if exists demo;
create database demo default character set utf8;
use demo;
drop table if exists book; create table book
(
id int not null auto_increment,
name varchar(20),
price decimal(8,2),
remark longtext,
storage int,
primary key (id)
); /* 图书测试用例 */
insert into book (name,price,remark,storage) values ('Java编程思想',99.99,'Java学习必读经典,殿堂级著作!赢得了全球程序员的广泛赞誉',200);
insert into book (name,price,remark,storage) values ('HTML5与CSS3权威指南',49.99,'一本前端应用开发的书籍',300);
insert into book (name,price,remark,storage) values ('Android从入门到精通',79.99,'移动互联网书籍',100); select * from book;

执行SQL语句结果如下:

根据表生成Java的model(模型)

 public class Book {

     private Integer id;
private String name;
private Double price;
private String remark;
public Integer storage; // ..... 省略了 set get方法
}

编写一个BookDaoImpl完成数据的插入功能

 public class BookDaoImpl {

     public int save(Book book) {
String sql = "insert into book (name,price,remark,storage) values (?,?,?,?)";
Connection conn = null;
PreparedStatement pre = null;
try {
conn = JdbcUtils.getConnection();
System.out.println("BookDaoImpl conn:" + conn);
pre = conn.prepareStatement(sql);
pre.setString(1, book.getName());
pre.setDouble(2, book.getPrice());
pre.setString(3, book.getRemark());
pre.setInt(4, book.getStorage());
return pre.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
pre.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}

编写一个AuthorDaoImpl完成作者插入功能(主要是为了测试事务, 如果两个方法有一个方法执行失败,则事务要回滚)

public class AuthorDaoImpl {

    public int save() {
Connection conn = JdbcUtils.getConnection();
System.out.println("AuthorDaoImpl conn:" + conn);
System.out.println("----另一张表插入作者信息-----");
// Integer.parseInt("xxxx");
return 0;
}
}

最后编写一个Service把需要的事务操作整合起来, Conn的创建与销毁都在Service中.

 public class BookServiceImpl {

     private BookDaoImpl bookDaoImpl = new BookDaoImpl();
private AuthorDaoImpl authorDaoImpl = new AuthorDaoImpl(); public static void main(String[] args) {
BookServiceImpl serviceImpl=new BookServiceImpl();
serviceImpl.save();
System.out.println("---------------------over------------------------");
} // 业务逻辑完成之后调用数据访问层,来实现数据入库
public void save(){
Connection conn = null;
try{
conn = JdbcUtils.getConnection();
// 手动提交事务
conn.setAutoCommit(false);
// 事务应该在业务逻辑层创建,包含所有事务的dao
bookDaoImpl.save(new Book(null, "测试书籍", 45.67, "我是备注", 100));
System.gc(); // 手动调用垃圾回收并不会导致弱引用Connection关闭,因为当前处于Open状态
authorDaoImpl.save();
conn.commit();
}catch (Exception e) {
try {
System.out.println("conn.rollback()");
conn.rollback();
} catch (SQLException e1) {
throw new RuntimeException(e1);
}
throw new RuntimeException(e);
}finally{
JdbcUtils.closeConnection(); // 必须要关闭,否则不会被销毁.因为Connecion默认是open状态
}
}
}

测试结果如下(通过测试我们会发现,两个Dao中使用的是同一个事务,如果出错事务将会回滚,在测试的时候会发现如果调用的gc也不会导致弱引用的Connection回收, 为什么呢,因为Connection是Open状态,只要没有关闭是不会被回收的,理解相信的原理可以参考当前文章的视频教程)

04_ThreadLocal整合事务操作的更多相关文章

  1. Winform开发框架里面使用事务操作的原理及介绍

    在很多情况下,事务是个很有用的东西,可以把一系列的操作组合成一个原子粒度的操作,一旦组合中某个地方出错,可以整个干净的进行滚回,不会留下脏数据:除此之外,事务还能提高批量操作的效率,如在本地SQLit ...

  2. spring学习(三) ———— spring事务操作

    前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...

  3. Spring 中的事务操作、注解、以及 XML 配置

    事务 事务全称叫数据库事务,是数据库并发控制时的基本单位,它是一个操作集合,这些操作要么不执行,要么都执行,不可分割.例如我们的转账这个业务,就需要进行数据库事务的处理. 转账中至少会涉及到两条 SQ ...

  4. spring(三) spring事务操作

    前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...

  5. Yii2 事务操作

    官网关于Yii2 事务的说明文档 http://www.yiiframework.com/doc-2.0/guide-db-active-record.html Working with Transa ...

  6. [PHP] - PDO事务操作

    PHP使用PDO事务操作数据库. 参考文章: http://php.ncong.com/mysql/pdo/pdo_shiwu.html 上代码: <!doctype html> < ...

  7. andorid SQLite数据库的增删改查 和事务操作

    .xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...

  8. Entity Framework 4 数据事务操作

    利用数据库链接进行事务操作 var db = ConnectionHelper.GetConn(ConnectionType.Write);//获取上下文 var conn = db.Connecti ...

  9. 使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解

    SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常 ...

随机推荐

  1. 函数补充:动态参数,函数嵌套,global与nonlocal关键

    一丶动态参数 1.*args 位置参数,动态传参 def func(*food): print(food) print(func("米饭","馒头"," ...

  2. 前端HTML以及HTML5(基本标签)

    前面一章介绍了一下前端的发展,这章简单介绍一下html的发展以及基本的标签. 一.HTML的发展史 1.概念 超文本标记语言(HyperText Markup Language,简称HTML)是为 [ ...

  3. this的那点事

    对于很多初学者,this总是搞得我们晕头转向. 现在,我就简单的总结一下关于this的那点事. this在函数定义时经常是不能确定的,只有在函数执行的时候才能最终确定this的归属.this总是指向最 ...

  4. 关于Linux系统启动时出现UVD not responding, Trying to reset the vcpu问题的解决

    本人的老古董笔记本!不知道什么时候显卡烧坏了 每次启动Linux的时候就会出现错误,信息如下: UVD not responding, trying to reset the VCPU! 讲道理,显卡 ...

  5. Appium基础三:Appium实现原理

    1.web自动化测试用的selenium webdriver 是c/s模式,server端和client端是通过webdriver protocol实现的,而Appium是参考selenium开发的, ...

  6. python爬虫之路——无头浏览器初识及简单例子

    from selenium import webdriver url='https://www.jianshu.com/p/a64529b4ccf3' def get_info(url): inclu ...

  7. 如何从Ubuntu 16.04 LTS升级到Ubuntu 18.04 LTS

    可以说非常简单(假设过程顺利!!) 您只需打开Software&Update,进入"Updates"选项卡,然后从“有新版本时通知我”下拉菜单中选择“适用长期支持版”选项. ...

  8. Leetcode重点 250题-前400 题

    删除不常考,面试低频出现题目 删除重复代码题目(例:链表反转206题,代码在234题出现过) 删除过于简单题目(例:100题:Same Tree) 删除题意不同,代码基本相同题目(例:136 & ...

  9. PAT (Basic Level) Practise (中文)- 1009. 说反话 (20)

    http://www.patest.cn/contests/pat-b-practise/1009 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在 ...

  10. javaweb基础(21)_两种开发模式

    SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...