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声明式事务 ...
随机推荐
- Oppotunity land---China
China is a land of opportunity.Following the development of China,every sector has made their contri ...
- 用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理
用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理 我测了一组数据存到txt文件中,是个WIFI信号强度文档,里面有我们需要得到的数据,有没用的数据,想用matla ...
- hdu 3807
很好的思路 枚举有多少人有ipad 判是否满足题目给出的条件 #include <iostream> #include <cstring> #include <c ...
- 被遗忘的Android mipmaps简介
被遗忘的 Android mipmaps 简介 [导读]已经发布的 Android Studio1.1 版本是一个 bug 修复版本.在这个版本中,当你创建工程时一项改变将会吸引你的眼球.工程创建登陆 ...
- POJ2217 Secretary 后缀数组&&高度数组
学后缀数组后的一道裸题.先来讲讲收获,作为字符串初学者,后缀数组也是刚刚在学,所幸的是有一篇好的论文<后缀数组--处理字符串的有力工具>by 罗穗骞,里面非常详尽地介绍了有关后缀数组的概念 ...
- POJ 1850
#include <iostream> #include <string> using namespace std; int fac(int num); int C(int n ...
- java基础知识回顾之---java String final类之intern方法
public class StringObjectDemo { /** * @param args */ public static void main(String[] args) { String ...
- 空格的URL编码
Q: 为什么我看的教材一会说是“+” 一会说是“%20” A: urlencode(" ") '返回+encodeURI(" ") '返回%20是有区别的
- crontab 指定执行用户
linux下可以通过配置crontab来定时执行任务,执行体可以是一条系统命令或自己写的一个脚本,同时可以指派用户来执行.配置crontab有两种方法.方法1.使用crontab命令,例如添加一个新的 ...
- Android service的开启和绑定,以及调用service的方法
界面: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...