jdbc事物的描述(JDBC事务和JTA事务的区别)

本文目录
- JDBC事务和JTA事务的区别
- jdbc的事务和jdbc传统的crud有什么区别
- java事务处理的详细说明
- Hibernate 基于JDBC的事务
- jdbc有哪些事务,各个事务特点
- 在java中,事务是什么有什么用!
JDBC事务和JTA事务的区别
一、事务概述
事务表示一个由一系列的数据库操作组成的不可分割的逻辑单位,其中的操作要么全做要么全都不做。
与事务相关的操作主要有:
BEGIN TRANSACTION; 开始一个事务,方法是:begin()
COMMIT; 提交一个事务,方法是:commit()
ROLLBACK; 回滚一个事务,方法是:rollback()
PREPARE; 准备提交一个事务,方法是:prepare()
二、事务的特性(ACID)
1、原子性:同一个事务的操作要么全部成功执行,要么全部撤消
2、隔离性:事务的所有操作不会被其它事务干扰
3、一致性:在操作过程中不会破坏数据的完整性
4、时效性 :事务的结果必须持久保存于介质上
三、事务处理方式
在JDBC连接中,使用命令声明事务的开始、提交和取消。如前一章介绍的数据库处理方式,它通过java.sql.Connection接口实现,可以启用AutoCommit。这种方式使用简单,但性能较低。
利用JavaEE规范的JTA驱动程序。这种方式性能更好,是EJB和JMS的常用方式。
Java EE 的分布式事务服务包括5个层次:事务管理器、应用服务器、资源管理器、应用程序、通信资源管理器。
事务管理器:完成事务管理
应用服务器:为应用提供服务
资源管理器:连接相应的资源
应 用程 序:需要使用事务的应用
通信资源管理器:接收事务、传播事务
四、JDBC和JTA事务区别
简单的说 jta是多库的事务 jdbc是单库的事务
jdbc的事务和jdbc传统的crud有什么区别
在jdbc的数据库操作中,一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元。我们通过提交commit()或是回滚rollback()来结束事务的操作。关于事务操作的方法都位于接口java.sql.Connection中。
2. 特点:
★ 在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。
★ 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下:
try {
conn = DriverManager.getConnection ;
conn.setAutoCommit(false);//禁止自动提交,设置回滚点
stmt = conn.createStatement();
stmt.executeUpdate(“alter table …”); //数据库更新操作1
stmt.executeUpdate(“insert into table …”); //数据库更新操作2
conn.commit(); //事务提交
}catch(Exception ex) {
ex.printStackTrace();
try {
conn.rollback(); //操作不成功则回滚
}catch(Exception e) {
e.printStackTrace();
}
}
最后一句话,传统CRUD就是走一步算一步,事务就是要做一起做,要不就都撤销。
java事务处理的详细说明
Java中使用事务处理,首先要求数据库支持事务。如使用MySQL的事务功能,就要求MySQL的表类型为Innodb才支持事务。否则,在Java程序中做了commit或rollback,但在数据库中根本不能生效。
JavaBean中使用JDBC方式进行事务处理
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事务的默认提交方式
dbc.executeUpdate(delete from xiao where ID= + sID);
dbc.executeUpdate(delete from xiao_content where ID= + sID);
dbc.executeUpdate(delete from xiao_affix where bylawid= + sID);
con.commit();//提交JDBC事务
con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滚JDBC事务
exc.printStackTrace();
dbc.close();
return -1;
}
}
在数据库操作中,一项事务是指由一条或多条对数据库更新的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作没有完成,就必须撤消整个事务。
例如在银行的转帐事务中,假定张三从自己的帐号上把1000元转到李四的帐号上,相关的sql语句如下:
update account set monery=monery-1000 where name=’zhangsan’
update account set monery=monery+1000 where name=’lisi’
这个两条语句必须作为一个完成的事务来处理。只有当两条都成功执行了,才能提交这个事务。如果有一句失败,整个事务必须撤消。
在connection类中提供了3个控制事务的方法:
(1) setAutoCommit(Boolean autoCommit):设置是否自动提交事务;
(2) commit();提交事务;
(3) rollback();撤消事务;
在jdbc api中,默认的情况为自动提交事务,也就是说,每一条对数据库的更新的sql语句代表一项事务,操作成功后,系统自动调用commit()来提交,否则将调用rollback()来撤消事务。
在jdbc api中,可以通过调用setAutoCommit(false) 来禁止自动提交事务。然后就可以把多条更新数据库的sql语句做为一个事务,在所有操作完成之后,调用commit()来进行整体提交。倘若其中一项 sql操作失败,就不会执行commit()方法,而是产生相应的sqlexception,此时就可以捕获异常代码块中调用rollback()方法撤消事务。
事务处理是企业应用需要解决的最主要的问题之一。J2EE通过JTA提供了完整的事务管理能力,包括多个事务性资源的管理能力。但是大部分应用都是运行在单一的事务性资源之上(一个数据库),他们并不需要全局性的事务服务。本地事务服务已然足够(比如JDBC事务管理)。
Hibernate 基于JDBC的事务
Hibernate 是JDBC 的轻量级封装 本身并不具备事务管理能力 在事务管理层 Hibernate将其委托给底层的JDBC或者JTA 以实现事务管理和调度功能
Hibernate的默认事务处理机制基于JDBC Transaction 我们也可以通过配置文件设定采用JTA作为事务管理实现
Java代码
- 《hibernate configuration》 《session factory》 …… 《property name= hibernate transaction factory_class 》 net sf hibernate transaction JTATransactionFactory 《! net sf hibernate transaction JDBCTransactionFactory 》 《/property》 …… 《/session factory》 《/hibernate configuration》
《hibernate configuration》 《session factory》 …… 《property name= hibernate transaction factory_class 》 net sf hibernate transaction JTATransactionFactory 《! net sf hibernate transaction JDBCTransactionFactory 》 《/property》 …… 《/session factory》 《/hibernate configuration》
基于JDBC的事务管理 将事务管理委托给JDBC 进行处理无疑是最简单的实现方式 Hibernate 对于JDBC事务的封装也极为简单 我们来看下面这段代码 Java代码- session = sessionFactory openSession(); Transaction tx = session beginTransaction(); …… mit();
session = sessionFactory openSession(); Transaction tx = session beginTransaction(); …… mit();
从JDBC层面而言 上面的代码实际上对应着 Java代码- Connection dbconn = getConnection(); dbconn setAutoCommit(false); …… mit();
Connection dbconn = getConnection(); dbconn setAutoCommit(false); …… mit();
就是这么简单 Hibernate并没有做更多的事情(实际上也没法做更多的事情) 只是将这样的JDBC代码进行了封装而已 这里要注意的是 在sessionFactory openSession()中 hibernate会初始化数据库连接 与此同时 将其AutoCommit 设为关闭状态(false) 而其后 在Session beginTransaction 方法中 Hibernate 会再次确认Connection 的AutoCommit 属性被设为关闭状态( 为了防止用户代码对session 的Connection AutoCommit属性进行修改) 这也就是说 我们一开始从SessionFactory获得的session 其自动提交属性就已经被关闭(AutoCommit=false) 下面的代码将不会对数据库产生任何效果 Java代码- session = sessionFactory openSession(); session save(user); session close();
session = sessionFactory openSession(); session save(user); session close();
这实际上相当于 JDBC Connection的AutoCommit属性被设为false 执行了若干JDBC操作之后 没有调用mit操作即将Connection关闭 如果要使代码真正作用到数据库 我们必须显式的调用Transaction指令 Java代码- session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(user); mit(); session close();
session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(user); mit(); session close();
基于JTA的事务管理 JTA 提供了跨Session 的事务管理能力 这一点是与JDBC Transaction 最大的差异 JDBC事务由Connnection管理 也就是说 事务管理实际上是在JDBC Connection中实现 事务周期限于Connection的生命周期之类 同样 对于基于JDBC Transaction的Hibernate 事务管理机制而言 事务管理在Session 所依托的JDBC Connection中实现 事务周期限于Session的生命周期 JTA 事务管理则由 JTA 容器实现 JTA 容器对当前加入事务的众多Connection 进 行调度 实现其事务性要求 JTA的事务周期可横跨多个JDBC Connection生命周期 同样对于基于JTA事务的Hibernate而言 JTA事务横跨可横跨多个Session JTA 事务是由JTA Container 维护 而参与事务的Connection无需对事务管理进行干涉 这也就是说 如果采用JTA Transaction 我们不应该再调用HibernateTransaction功能 上面基于JDBC Transaction的正确代码 这里就会产生问题 Java代码- public class ClassA{ public void saveUser(User user){ session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(user); mit(); session close(); } } public class ClassB{ public void saveOrder(Order order){ session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(order); mit(); session close(); } } public class ClassC{ public void save(){ …… UserTransaction tx = new InitialContext() lookup( …… ); ClassA save(user); ClassB save(order); mit(); …… } }
public class ClassA{ public void saveUser(User user){ session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(user); mit(); session close(); } } public class ClassB{ public void saveOrder(Order order){ session = sessionFactory openSession(); Transaction tx = session beginTransaction(); session save(order); mit(); session close(); } } public class ClassC{ public void save(){ …… UserTransaction tx = new InitialContext() lookup( …… ); ClassA save(user); ClassB save(order); mit(); …… } }
这里有两个类ClassA和ClassB 分别提供了两个方法 saveUsersaveOrder 用于保存用户信息和订单信息 在ClassC中 我们接连调用了ClassA saveUser方法和ClassB saveOrder 方法 同时引入了JTA 中的UserTransaction 以实现ClassC save方法中的事务性 问题出现了 ClassA 和ClassB 中分别都调用了Hibernate 的Transaction 功能 在Hibernate 的JTA 封装中 Session beginTransaction 同样也执行了InitialContext lookup方法获取UserTransaction实例 mit方法同样也调用了mit方法 实际上 这就形成了两个嵌套式的JTA Transaction ClassC 申明了一个事务 而在ClassC 事务周期内 ClassA 和ClassB也企图申明自己的事务 这将导致运行期错误 因此 如果决定采用JTA Transaction 应避免再重复调用Hibernate 的 Transaction功能 上面的代码修改如下 Java代码- public class ClassA{ public void save(TUser user){ session = sessionFactory openSession(); session save(user); session close(); } …… } public class ClassB{ public void save (Order order){ session = sessionFactory openSession(); session save(order); session close(); } …… } public class ClassC{ public void save(){ …… UserTransaction tx = new InitialContext() lookup( …… ); classA save(user); classB save(order); mit(); …… } }
public class ClassA{ public void save(TUser user){ session = sessionFactory openSession(); session save(user); session close(); } …… } public class ClassB{ public void save (Order order){ session = sessionFactory openSession(); session save(order); session close(); } …… } public class ClassC{ public void save(){ …… UserTransaction tx = new InitialContext() lookup( …… ); classA save(user); classB save(order); mit(); …… } }
上面代码中的ClassC save方法 也可以改成这样 Java代码- public class ClassC{ public void save(){ …… session = sessionFactory openSession(); Transaction tx = session beginTransaction(); classA save(user); classB save(order); mit(); …… } }
- /** * @ejb interface method * view type= remote * * @ejb transaction type = Required **/ public void save(){ //EJB环境中 通过部署配置即可实现事务申明 而无需显式调用事务 classA save(user); classB save(log); }//方法结束时 如果没有异常发生 则事务由EJB容器自动提交
jdbc有哪些事务,各个事务特点
事务的:原子性、一致性、分离性、持久性
原子性、一致性、分离性、持久性
(1) 原子性
事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行。这种特性称为原子性。
事务的原子性要求,如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。就是说事务的操纵序列或者完全应用到数据库或者完全不影响数据库。这种特性称为原子性。
假如用户在一个事务内完成了对数据库的更新,这时所有的更新对外部世界必须是可见的,或者完全没有更新。前者称事务已提交,后者称事务撤消(或流产)。DBMS必须确保由成功提交的事务完成的所有操纵在数据库内有完全的反映,而失败的事务对数据库完全没有影响。
(2) 一致性
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。
一致性处理数据库中对所有语义约束的保护。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。例如,当数据库处于一致性状态S1时,对数据库执行一个事务,在事务执行期间假定数据库的状态是不一致的,当事务执行结束时,数据库处在一致性状态S2。
(3) 分离性
分离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到。
分离性是DBMS针对并发事务间的冲突提供的安全保证。DBMS可以通过加锁在并发执行的事务间提供不同级别的分离。假如并发交叉执行的事务没有任何控制,操纵相同的共享对象的多个并发事务的执行可能引起异常情况。
DBMS可以在并发执行的事务间提供不同级别的分离。分离的级别和并发事务的吞吐量之间存在反比关系。较多事务的可分离性可能会带来较高的冲突和较多的事务流产。流产的事务要消耗资源,这些资源必须要重新被访问。因此,确保高分离级别的DBMS需要更多的开销。
(4)持久性
持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,耐得住任何系统故障。持久性通过数据库备份和恢复来保证。
持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即对已提交事务的更新能恢复。一旦一个事务被提交,DBMS必须保证提供适当的冗余,使其耐得住系统的故障。所以,持久性主要在于DBMS的恢复性能。
在java中,事务是什么有什么用!
一、什么是Java事务
通常的观念认为,事务仅与数据库相关。
事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性
(isolation)和持久性(durability)的缩写。事务的原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。一致性表示
当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。隔离性表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。持
久性表示已提交的数据在事务执行失败时,数据的状态都应该正确。
通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行。
既然事务的概念从数据库而来,那Java事务是什么?之间有什么联系?
实际上,一个Java应用系统,如果要操作数据库,则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的,事务的控制也相应转移到Java程序代码中。因此,数据库操作的事务习惯上就称为Java事务。
二、为什么需要事务
事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。具一个简单例子:比如银行转帐业务,账户A要将自己账户上的1000元
转到B账户下面,A账户余额首先要减去1000元,然后B账户要增加1000元。假如在中间网络出现了问题,A账户减去1000元已经结束,B因为网络中
断而操作失败,那么整个业务失败,必须做出控制,要求A账户转帐业务撤销。这才能保证业务的正确性,完成这个操走就需要事务,将A账户资金减少和B账户资
金增加方到一个事务里面,要么全部执行成功,要么操作全部撤销,这样就保持了数据的安全性。
三、Java事务的类型
Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。
1、JDBC事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。
2、JTA(Java Transaction API)事务
JTA是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。
JTA允许应用程序执行分布式事务处理–在两个或多个网络计算机资源上访问并且更新数据,这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能力。
如果计划用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、
javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC
驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection
对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。
您将需要用应用服务器的管理工具设置 XADataSource 。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。
J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用 javax.sql.DataSource.getConnection() 以获得到数据库的连接。
XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC
的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者
java.sql.Connection.rollback() 。相反,应用程序应该使用 UserTransaction.begin()、
UserTransaction.commit() 和 serTransaction.rollback() 。
3、容器事务
容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。相对编码实现JTA事
务管理,我们可以通过EJB容器提供的容器事务管理机制(CMT)完成同一个功能,这项功能由J2EE应用服务器提供。这使得我们可以简单的指定将哪个方
法加入事务,一旦指定,容器将负责事务管理任务。这是我们土建的解决方式,因为通过这种方式我们可以将事务代码排除在逻辑编码之外,同时将所有困难交给
J2EE容器去解决。使用EJB CMT的另外一个好处就是程序员无需关心JTA API的编码,不过,理论上我们必须使用EJB。
四、三种事务差异
1、JDBC事务控制的局限性在一个数据库连接内,但是其使用简单。
2、JTA事务的功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。
3、容器事务,主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。
五、总结
事务控制是构建J2EE应用不可缺少的一部分,合理选择应用何种事务对整个应用系统来说至关重要。一般说来,在单个JDBC
连接连接的情况下可以选择JDBC事务,在跨多个连接或者数据库情况下,需要选择使用JTA事务,如果用到了EJB,则可以考虑使用EJB容器事务。
如果满意请及时采纳,谢谢~

更多文章:
session已过期重新授权(苹果手机session过期怎么恢复啊)
2026年3月8日 10:00
scrapy中间件(scrapy框架中setting中中间件数字大的先执行么)
2026年8月22日 13:45
matlab定义变量并赋初值(在matlab中用输入量给变量赋值)
2026年6月11日 15:00
程序设计语言是如何通过a b+1的(C语言中c=(a+b,a++,b+1);什么意思)
2026年6月29日 19:30
apache中国官网(中国sns交友网站排行前十名分别是什么)
2025年6月30日 20:45
eclipse创建的项目在哪里(Eclipse的src文件在哪里啊)
2026年8月31日 03:15
什么是函数?js正则查找match()与替换replace()用法实例
2025年9月29日 19:00
frameset标签的属性(在html标签中的frameset是什么标签 又有哪些属性和值)
2025年12月6日 02:15
translate最新消息(‘请以最新的信息为准’ 怎么翻译)
2026年6月5日 08:00
thymeleaf使用ajax(如何在Thymeleaf中实现ajax请求url的可靠构造)
2025年6月24日 09:00















