04_ThreadLocal整合事务操作
文章导读:
本文主要讲解了如何在没有框架情况下如何解决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整合事务操作的更多相关文章
- Winform开发框架里面使用事务操作的原理及介绍
在很多情况下,事务是个很有用的东西,可以把一系列的操作组合成一个原子粒度的操作,一旦组合中某个地方出错,可以整个干净的进行滚回,不会留下脏数据:除此之外,事务还能提高批量操作的效率,如在本地SQLit ...
- spring学习(三) ———— spring事务操作
前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...
- Spring 中的事务操作、注解、以及 XML 配置
事务 事务全称叫数据库事务,是数据库并发控制时的基本单位,它是一个操作集合,这些操作要么不执行,要么都执行,不可分割.例如我们的转账这个业务,就需要进行数据库事务的处理. 转账中至少会涉及到两条 SQ ...
- spring(三) spring事务操作
前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...
- Yii2 事务操作
官网关于Yii2 事务的说明文档 http://www.yiiframework.com/doc-2.0/guide-db-active-record.html Working with Transa ...
- [PHP] - PDO事务操作
PHP使用PDO事务操作数据库. 参考文章: http://php.ncong.com/mysql/pdo/pdo_shiwu.html 上代码: <!doctype html> < ...
- andorid SQLite数据库的增删改查 和事务操作
.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...
- Entity Framework 4 数据事务操作
利用数据库链接进行事务操作 var db = ConnectionHelper.GetConn(ConnectionType.Write);//获取上下文 var conn = db.Connecti ...
- 使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解
SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常 ...
随机推荐
- Java运算符、引用数据类型、流程控制语句
1运算符 1.1算术运算符 运算符是用来计算数据的符号. 数据可以是常量,也可以是变量. 被运算符操作的数我们称为操作数. 算术运算符最常见的操作就是将操作数参与数学计算: 运算符 运算规则 范例 结 ...
- Vue Scroller:Vue 下拉刷新及无限加载组件
Vue Scroller Vue Scroller is a foundational component ofVonic UI. In purpose of smooth scrolling, pu ...
- 前端HTML以及HTML5(基本标签)
前面一章介绍了一下前端的发展,这章简单介绍一下html的发展以及基本的标签. 一.HTML的发展史 1.概念 超文本标记语言(HyperText Markup Language,简称HTML)是为 [ ...
- 常用的图片相关方法,读取,保存,压缩,缩放,旋转,drawable转化
import android.content.Context; import android.content.res.AssetManager; import android.content.res. ...
- mysql 5.7.20 在线安装与卸载(yum卸载与rpm卸载方式)
mysql5.7.20和之前的5.7.16版本不同,解压后没有data文件,需要自己建立 1.把下载的mysql5.7.20放到目录:/usr/local/2.卸载cenos上预装的mysql查看已安 ...
- 微信成为HTML5技术流行的最大推手
很多热点的事件都是厚积薄发,HTML5就是如此.此前iOS和Android系统已经放弃了Flash,这让HTML5有了一个天然的成长基础.而现在手机硬件的提升和HTML5本身的完善,使得基于HTML5 ...
- 【虚拟机-磁盘管理】理解及快速测定 Azure 虚拟机的磁盘性能
随着越来越多的用户将生产系统迁移到 Azure 平台的虚拟机服务中,Azure 虚拟机的性能愈发被关注.传统的数据中心中,我们通常使用 CPU,内存,存储和网络的性能来衡量生产压力.特别是对于 IO ...
- C#中Image类与byte[]之间的转换
//将image转化为二进制 public byte[] GetByteImage(Image img) { byte[] bt = null; if (!img.Equals(null)) { us ...
- POJ 1651 Multiplication Puzzle (区间DP,经典)
题意: 给出一个序列,共n个正整数,要求将区间[2,n-1]全部删去,只剩下a[1]和a[n],也就是一共需要删除n-2个数字,但是每次只能删除一个数字,且会获得该数字与其旁边两个数字的积的分数,问最 ...
- ASP.NET WebForm & MongoDB
ASP.NET WebForm & MongoDB 最近在朋友介绍下,也跟着看AngularJS 买了一本三合一的书,Node.JS+MongoDB+AngularJS http://www. ...