JDBC 事务控制
一、简介:
前面一遍提到了jdbc事务相关的概念。从中了解到事务应具有ACID特性。所以对于javaweb开发来说,某一个service层的方法,应该是一个事务,应该是具有原子性的。特别是当一个service方法中需要调用多次dao层的方法。应该必须要保证,这些多次调用的dao方法必须是要不全部执行成功。要不全部执行失败。比如说银行业务的service方法的转账方法,需要通过dao调用对源转账户信息进行更新减少指定金额,然后调用dao对目标账户信息进行更新增加指定金额。
那么如下保证在跨dao层调用时,必须事务的acid特性呢?
二、解决方法思路:
保证事务的ACID特性,默认情况下对用jdbc对数据库进行操作事务都是自动的commit状态的。必须必须要将事务提交改成手动提交。由程序来控制什么一起向数据库提交。一般来说mysql、sql server与oracle默认的隔离级别是repeatable read级别。可以避免脏读与不可重复读。所以需要重点控制的是事务的提交与回滚。
那么一个service方法跨多个dao方法调用,如何保证是一个事务呢?首先要保证是同一连接Connection才有可能保证是同一事务。接着需要关注的是如何在多个dao层中获取是同一Connection。让整个应用只有个Connection虽然可以解决同一Connection,但是应用就变成了单线程了。肯定不可以。那么多线程情况下,如何保证同一线程内获取的Connection都是同一对象呢?ThreadLocal类来帮忙,它可以提供线程局部变量。放入到此ThreadLocal中的对象,在同一线程都保证都到的对象都是一致的。
解决方法:只需要编写一个TransactionUtils类,此类有一个private static的ThreadLocal tl对象。并且静态的getConnction方法体中,先判断tl对象中是否存在Connection对象,存在直接返回tl中的Connection。不存在则先用数据源获取个Connection对象然后放入到tl中,再返回Connection对象。此外TransactionUtils类还需要提供openTransaction方法、Commit方法、rollback方法,openTransaction、commit与rollback需要的Connection对象都直接找本类的getConnection方法。
接着后面service层,先调用TransactionUtils类的openTransaction方法,再对所有的dao层调用方法都try ... Catch...finally下。Catch中调用TransactionUtils类的rollback方法。finally里中调用 TransactionUtils类的commit方法。
而dao层获取的Connection都直接找TransactionUtils类的getConnection方法,来确认得到的都是同一Connection对象。
三、示例代码如下:
01public class TransactionUtil {
02 private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
03 private static DataSource ds;
04
05 static {
06 try {
07 InputStream in = DbcpUtil.class.getClassLoader()
08 .getResourceAsStream("dbcpconfig.properties");
09 Properties props = new Properties();
10 props.load(in);
11 ds = BasicDataSourceFactory.createDataSource(props);
12 } catch (Exception e) {
13 throw new ExceptionInInitializerError(e);
14 }
15 }
16
17 public static DataSource getDataSource() {
18 return ds;
19 }
20
21 public static Connection getConnection() {
22 Connection conn = tl.get(); // 从ThreadLoacl中获取,如果没有再从DataSource中获取
23 if (conn == null) {
24 try {
25 conn = ds.getConnection();
26 tl.set(conn); // 存到ThreadLoacl中
27 } catch (SQLException e) {
28 e.printStackTrace();
29 }
30 }
31 return conn;
32 }
33
34 public static void startTransaction() {
35 try {
36 Connection conn = tl.get();
37 if(conn == null) { //如果ThreadLoacl中没有,就从DataSource中获取
38 conn = ds.getConnection();
39 tl.set(conn); //存入
40 }
41 conn.setAutoCommit(false);
42 } catch(Exception e) {
43 e.printStackTrace();
44 }
45 }
46
47 public static voidrollback() { <span style="font-family: 'Courier New'; ">//回滚事务,在service层try下dao层,在catch处调用rollbakc方法</span>
48 try {
49 Connection conn = tl.get();
50 if(conn != null)
51 conn.rollback();
52 } catch(Exception e) {
53 e.printStackTrace();
54 }
55 }
56
57 public static voidcommit() { <span style="font-family: 'Courier New'; ">//在finally里调用提交commint方法</span>
58 try {
59 Connection conn = tl.get();
60 if(conn != null)
61 conn.commit();
62 } catch(Exception e) {
63 e.printStackTrace();
64 }
65 }
66
67 public static void release() {
68 try {
69 Connection conn = tl.get();
70 if(conn != null) {
71 conn.close();
72 tl.remove();
73 }
74 } catch(Exception e) {
75 e.printStackTrace();
76 }
77 }
78
79}
JDBC 事务控制的更多相关文章
- JDBC事务控制管理(转载)
JDBC事务控制管理 转载于 2018年01月26日 15:46:11 1.事务 (1)事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐, ...
- 分层架构下的纯JDBC事务控制简单解决方案【转】
http://blog.csdn.net/qjyong/article/details/5464835 对目前的JavaEE企业应用开发来说,基本都会采用分层的架构, 这样可以分散关注.松散耦合.逻辑 ...
- JDBC事务控制管理
1.事务 (1)事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐,对应于如下两条sql语句 update account set mone ...
- JDBC事务控制
概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并 ...
- 事务和JDBC事务隔离级别
与事务相关的理论 mysql事物隔离级别:http://mj4d.iteye.com/blog/1744276 事务(Transaction): 是并发控制的单元,是用户定义的一个操作序列.这些操作要 ...
- jdbc事务、连接池概念、c3p0、Driud、JDBC Template、DBUtils
JDBC 事务控制 什么是事务:一个包含多个步骤或者业务操作.如果这个业务或者多个步骤被事务管理,则这多个步骤要么同时成功,要么回滚(多个步骤同时执行失败),这多个步骤是一个整体,不可分割的. 操作: ...
- spring入门(三)【事务控制】
在开发中需要操作数据库,进行增.删.改操作的过程中属于一次操作,如果在一个业务中需要更新多张表,那么任意一张表的更新失败,整个业务的更新就是失败,这时那些更新成功的表必须回滚,否则业务会出错,这时就要 ...
- JTA和JDBC事务
一般情况下,J2EE应用服务器支持JDBC事务.JTA事务.容器管理事务.这里讨论JTA和JDBC事务的区别.这2个是常用的DAO模式事务界定方式.JDBC 事务 JDBC 事务是用 Connecti ...
- Spring中的Jdbc事务管理
Spring提供了对事务的声明式事务管理,只需要在配置文件中做一些配置,即可把操作纳入到事务管理当中,解除了和代码的耦合. Spring声明式事务管理,核心实现就是基于Aop. Spring声明式事务 ...
随机推荐
- vs2013中头文件中大小写的切换的快捷键
1.选中内容 2.ctrl+shift+u 例如: #include "LayerStart.h" -> #include "LAYERSTART.H&q ...
- Week1 Team Homework #2 Introduction of team member with photos
小组成员介绍 组长:黄剑锟 11061164 组员:顾泽鹏 11061160 组员:周辰光 11061154 组员:龚少波 11061167 组 ...
- 在MAC上安装虚拟机搭建Ubuntu开发环境
由于工作需要,需要在LINUX环境搭建服务器,但是工作中使用的是MAC系统,只好用虚拟机来搭建LINUX服务器环境.下面记录介绍一下搭建步骤以供需要的人参考使用. 下载准备 虚拟机使用VMWare ...
- smarty中的母板极制_extends和block标签
模板继承 继承是从面向对象编程而来的概念,模板继承可以让你定义一个或多个父模板,提供给子模板来进行扩展. 扩展继承意味着子模板可以覆盖部分或全部父模板的块区域. 继承结构可以是多层次的,所以你可以继承 ...
- 【Asp.net MVC ---杂七杂八】
@RenderSection 母模板:_mainLayout.cshtml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...
- jQuery中的&& ||
jQuery1.2.6 clean方法中有这么一段第一眼看去会让人晕掉的方法.完全不知其所言. “||, && 可以这样用?”,“这段东西最终返回的是个什么对象啊?” // Trim ...
- Web中的监听器【Listener】
Servlet监听器:Servlet规范中定义的一种特殊类,它用于监听Web应用程序中的ServletContext.HttpSession和ServletRequest等域对象的创建与销毁事件,以及 ...
- java:I/O流
I/O是input/output的缩写,即输入输出端口. 从 文件.键盘.网络 等输入到java程序,再从java程序输出到 文件.显示器.网络等 分类: 1.输入流 和 输出流2.字节流 和 字符流 ...
- notepad++每行首尾添加内容
有时候我们需要给一个文本文件的每行前面或后面添加一些内容,例如我们一个文本文件里存放了很多图片的地址,现在我们需要把这些图片批量转换成html标记 百度经验:jingyan.baidu.com 工具/ ...
- 利用PhantomJS搭建Highcharts export服务
利用PhantomJS搭建Highcharts export服务 一直在使用Highcharts做web图表的展示, 但是当发送定时的报表邮件的遇到了这个问题. 为了保证邮件图表和web页图表样式一致 ...