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 事物支持 : 不支持 ...
随机推荐
- django之创建第2个项目
如上为项目结构 1.创建项目helloworld 2.把目录切换到django/helloworld目录下创建blog站点 3.需要修改的信息如下: 1)修改blog站点的views.py # Cre ...
- python 怎么模拟加header(如User-Agent、Content-Type等等)
# -*- coding: cp936 -*- #python 27 #xiaodeng #python 怎么模拟加header(如User-Agent.Content-Type等等) #办法一: i ...
- 利用LD_PRELOAD hook代码
loader在进行动态链接的时候,会将有相同符号名的符号覆盖成LD_PRELOAD指定的so文件中的符号.换句话说,可以用我们自己的so库中的函数替换原来库里有的函数,从而达到hook的目的.这和Wi ...
- java struts2入门学习实例--使用struts2快速实现多个文件上传
一.错误提示信息配置 昨天说到更改默认错误配置信息,我测试很多遍,一直都不对.下面贴出来,待以后有好方法了再补充吧. 首先新建一个properties文件,这里命名为testupload.proper ...
- JavaScript 消息框,警告框,确认框,提示框
1.警告框 警告框经常用于确保用户可以得到某些信息. 当警告框出现后,用户需要点击确定按钮才能继续进行操作. 语法: alert("文本") 2.确认框 确认框用于使用户可以验证或 ...
- java hibernate session create
public class RegisterStory { private SysUserCDao sysUserCDao; @Test public void test() { SessionFact ...
- 【LeetCode】229. Majority Element II
Majority Element II Given an integer array of size n, find all elements that appear more than ⌊ n/3 ...
- C语言学习笔记 (002) - C++中引用和指针的区别(转载)
下面用通俗易懂的话来概述一下: 指针-对于一个类型T,T*就是指向T的指针类型,也即一个T*类型的变量能够保存一个T对象的地址,而类型T是可以加一些限定词的,如const.volatile等等.见下图 ...
- log4j(六)——log4j.properties简单配置样例说明
一:测试环境与log4j(一)——为什么要使用log4j?一样,这里不再重述 二:老规矩,先来个栗子,然后再聊聊感受 (1)使用配文件的方式,是不是感觉非常的清爽,如果不在程序中读取配置文件就更加的清 ...
- 轻量级验证码生成插件webutil-licenseImage源码与实例应用
webutil-licenseImage 插件内置4种验证码样式,支持用户扩展.自定义样式实现简单验证码. 源码脱管地址: http://code.google.com/p/licenseimage/ ...