JDBC 事务和 JTA 事务
Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。所以本文暂不讨论容器事务。本文主要介绍J2EE开发中两个比较基本的事务:JDBC事务和JTA事务。
JDBC事务
JDBC的一切行为包括事务是基于一个Connection的,在JDBC中是通过Connection对象进行事务管理。在JDBC中,常用的和事务相关的方法是: setAutoCommit、commit、rollback等。

下面看一个简单的JDBC事务代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public void JdbcTransfer() { java.sql.Connection conn = null; try{ conn = conn =DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd"); // 将自动提交设置为 false, //若设置为 true 则数据库将会把每一次数据更新认定为一个事务并自动提交 conn.setAutoCommit(false); stmt = conn.createStatement(); // 将 A 账户中的金额减少 500 stmt.execute("\ update t_account set amount = amount - 500 where account_id = 'A'"); // 将 B 账户中的金额增加 500 stmt.execute("\ update t_account set amount = amount + 500 where account_id = 'B'"); // 提交事务 conn.commit(); // 事务提交:转账的两步操作同时成功 } catch(SQLException sqle){ try{ // 发生异常,回滚在本事务中的操做 conn.rollback(); // 事务回滚:转账的两步操作完全撤销 stmt.close(); conn.close(); }catch(Exception ignore){ } sqle.printStackTrace(); } } |
上面的代码实现了一个简单的转账功能,通过事务来控制转账操作,要么都提交,要么都回滚。
JDBC事务的优缺点
JDBC为使用Java进行数据库的事务操作提供了最基本的支持。通过JDBC事务,我们可以将多个SQL语句放到同一个事务中,保证其ACID特性。JDBC事务的主要优点就是API比较简单,可以实现最基本的事务操作,性能也相对较好。
但是,JDBC事务有一个局限:一个 JDBC 事务不能跨越多个数据库!!!所以,如果涉及到多数据库的操作或者分布式场景,JDBC事务就无能为力了。
JTA事务
为什么需要JTA
通常,JDBC事务就可以解决数据的一致性等问题,鉴于他用法相对简单,所以很多人关于Java中的事务只知道有JDBC事务,或者有人知道框架中的事务(比如Hibernate、Spring)等。但是,由于JDBC无法实现分布式事务,而如今的分布式场景越来越多,所以,JTA事务就应运而生。
如果,你在工作中没有遇到JDBC事务无法解决的场景,那么只能说你做的项目还都太小。拿电商网站来说,我们一般把一个电商网站横向拆分成商品模块、订单模块、购物车模块、消息模块、支付模块等。然后我们把不同的模块部署到不同的机器上,各个模块之间通过远程服务调用(RPC)等方式进行通信。以一个分布式的系统对外提供服务。
一个支付流程就要和多个模块进行交互,每个模块都部署在不同的机器中,并且每个模块操作的数据库都不一致,这时候就无法使用JDBC来管理事务。我们看一段代码:
|
1
2
3
4
5
6
7
8
9
|
/** 支付订单处理 **/@Transactional(rollbackFor = Exception.class)public void completeOrder() { orderDao.update(); // 订单服务本地更新订单状态 accountService.update(); // 调用资金账户服务给资金帐户加款 pointService.update(); // 调用积分服务给积分帐户增加积分 accountingService.insert(); // 调用会计服务向会计系统写入会计原始凭证 merchantNotifyService.notify(); // 调用商户通知服务向商户发送支付结果通知} |
上面的代码是一个简单的支付流程的操作,其中调用了五个服务,这五个服务都通过RPC的方式调用,请问使用JDBC如何保证事务一致性?我在方法中增加了@Transactional注解,但是由于采用调用了分布式服务,该事务并不能达到ACID的效果。
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:JDBC连接、JDO PersistenceManager 对象、JMS 队列、JMS 主题、企业JavaBeans(EJB)、一个用J2EE Connector Architecture 规范编译的资源分配器。
JTA的优缺点
JTA的优点很明显,就是提供了分布式事务的解决方案,严格的ACID。但是,标准的JTA方式的事务管理在日常开发中并不常用,因为他有很多缺点:
- 实现复杂
通常情况下,JTA UserTransaction需要从JNDI获取。这意味着,如果我们使用JTA,就需要同时使用JTA和JNDI。
- JTA本身就是个笨重的API
- 通常JTA只能在应用服务器环境下使用,因此使用JTA会限制代码的复用性。
总结
Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务,其中JDBC的事务操作用法比较简单,适合于处理同一个数据源的操作。JTA事务相对复杂,可以用于处理跨多个数据库的事务,是分布式事务的一种解决方案。
这里还要简单说一下,虽然JTA事务是Java提供的可用于分布式事务的一套API,但是不同的J2EE平台的实现都不一样,并且都不是很方便使用,所以,一般在项目中不太使用这种较为负责的API。现在业内比较常用的分布式事务解决方案主要有异步消息确保型、TCC、最大努力通知等。
JDBC 事务和 JTA 事务的更多相关文章
- Java中的事务——JDBC事务和JTA事务
Java中的事务——JDBC事务和JTA事务 转载:http://www.hollischuang.com/archives/1658 之前的事务介绍基本都是数据库层面的事务,本文来介绍一下J2EE中 ...
- 数据库事务(1)----- JDBC事务与JTA事务
数据库事务(一)- JDBC事务与JTA事务 本文主要对JDBC事务与JTA事务做一个简单介绍. 1. 数据库事务概念 一个数据库事务通常包含对数据库进行读或写的一个操作序列.它的存在包含有以下两个目 ...
- JDBC事务和JTA事务的区别
转自:JDBC和JTA事务的区别 一.事务概述事务表示一个由一系列的数据库操作组成的不可分割的逻辑单位,其中的操作要么全做要么全都不做.与事务相关的操作主要有:BEGIN TRANSACTION: 开 ...
- 跟我学Spring3(9.1):Spring的事务之数据库事务概述
原文出处: 张开涛 9.1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致 ...
- Spring笔记(4) - Spring的编程式事务和声明式事务详解
一.背景 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作 ...
- 在Hibernate中分别使用JDBC和JTA事务的方法
在Hibernate中使用JDBC事务 Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能.Hibernate将底层的JDBCTransaction或JTATransa ...
- JDBC事务和JTA (XA)事务区别
JDBC 事务 JDBC 事务是用 Connection 对象控制的.JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交. 在jd ...
- 事务种类jdbc,Hibernate,JTA事务
JDBC事务 String URL="jdbc:sqlserver://localhost:1433;databaseName=test2"; String USER=" ...
- Innodb的事务与日志 & JTA事务
InnoDB引擎的行锁是通过加在什么上完成(或称实现)的?为什么是这样子的 通过 行多版本控制 MyISAM Innodb 事物支持 : 不支持 ...
随机推荐
- 分布式交易系统的并发处理, 以及用Redis和Zookeeper实现分布式锁
交易系统 交易系统的数据结构 支付系统API通常需要一个“订单号”作为入参, 而实际调用API接口时使用到的往往不是真正意义的业务订单号, 而是交易订单号. 支付系统的API会使用“商户号+订单号” ...
- 【CAS单点登录视频教程】 第06集【完】 -- Cas认证 学习 票据认证FormsAuthentication
目录 ----------------------------------------- [CAS单点登录视频教程] 第06集[完] -- Cas认证 学习 票据认证FormsAuthenticati ...
- (原+转)win7上编译caffe支持python及matlab
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/7126126.html 参考网址: https://github.com/happynear/caffe ...
- 每日学习与工作计划移至日事清APP
今天今天开始,每日学习与工作计划移至日事清APP. 博客园依然是我写文字的主战场.日事清APP仅限于做计划.
- python实现json转excel
import json import xlwt a = json.load(open("haha.json", encoding='utf8')) title = list(set ...
- Redis学习之路(007)- Redis学习手册(实例代码)
在之前的博客中已经非常详细的介绍了Redis的各种操作命令.运行机制和服务器初始化参数配置.本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例. ...
- OAuth2.0实战之微信授权篇
微信开发三大坑: 微信OAuth2.0授权 微信jssdk签名 微信支付签名 本篇先搞定微信OAuth2.0授权吧! 以简书的登陆页面为例,来了解一下oauth2.0验证授权的一些背景知识: 1) 传 ...
- SQL Server 表分区之水平表分区
什么是表分区? 表分区分为水平表分区和垂直表分区,水平表分区就是将一个具有大量数据的表,进行拆分为具有相同表结构的若干个表:而垂直表分区就是把一个拥有多个字段的表,根据需要进行拆分列,然后根据某一个字 ...
- 【C#】C#创建Windows Service服务
目录结构: contents structure [+] 创建Windows服务 配置 安装Windows服务 在Visual Studio中调试 常见问题 最近写了一个TCP连接的程序,由于这种通信 ...
- 【Visual Studio】Visual C# 中XML注释的使用(含注释在开发时显示换行)
为函数方法注释说明要用到 xml 语句 <summary> 段落说明 </summary> .<para> 新段示例说明 </para>.<par ...