文章导读:

本文主要讲解了如何在没有框架情况下如何解决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. Java运算符、引用数据类型、流程控制语句

    1运算符 1.1算术运算符 运算符是用来计算数据的符号. 数据可以是常量,也可以是变量. 被运算符操作的数我们称为操作数. 算术运算符最常见的操作就是将操作数参与数学计算: 运算符 运算规则 范例 结 ...

  2. Vue Scroller:Vue 下拉刷新及无限加载组件

    Vue Scroller Vue Scroller is a foundational component ofVonic UI. In purpose of smooth scrolling, pu ...

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

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

  4. 常用的图片相关方法,读取,保存,压缩,缩放,旋转,drawable转化

    import android.content.Context; import android.content.res.AssetManager; import android.content.res. ...

  5. mysql 5.7.20 在线安装与卸载(yum卸载与rpm卸载方式)

    mysql5.7.20和之前的5.7.16版本不同,解压后没有data文件,需要自己建立 1.把下载的mysql5.7.20放到目录:/usr/local/2.卸载cenos上预装的mysql查看已安 ...

  6. 微信成为HTML5技术流行的最大推手

    很多热点的事件都是厚积薄发,HTML5就是如此.此前iOS和Android系统已经放弃了Flash,这让HTML5有了一个天然的成长基础.而现在手机硬件的提升和HTML5本身的完善,使得基于HTML5 ...

  7. 【虚拟机-磁盘管理】理解及快速测定 Azure 虚拟机的磁盘性能

    随着越来越多的用户将生产系统迁移到 Azure 平台的虚拟机服务中,Azure 虚拟机的性能愈发被关注.传统的数据中心中,我们通常使用 CPU,内存,存储和网络的性能来衡量生产压力.特别是对于 IO ...

  8. C#中Image类与byte[]之间的转换

    //将image转化为二进制 public byte[] GetByteImage(Image img) { byte[] bt = null; if (!img.Equals(null)) { us ...

  9. POJ 1651 Multiplication Puzzle (区间DP,经典)

    题意: 给出一个序列,共n个正整数,要求将区间[2,n-1]全部删去,只剩下a[1]和a[n],也就是一共需要删除n-2个数字,但是每次只能删除一个数字,且会获得该数字与其旁边两个数字的积的分数,问最 ...

  10. ASP.NET WebForm & MongoDB

    ASP.NET WebForm & MongoDB 最近在朋友介绍下,也跟着看AngularJS 买了一本三合一的书,Node.JS+MongoDB+AngularJS http://www. ...