java事务总述

本文详细介绍了Java事务的概念,包括JDBC、JTA和容器事务的类型及其差异,强调了事务的ACID特性,并深入讲解了MySQL的四种隔离级别及解决脏读、幻读和不可重复读的方法。此外,还探讨了Spring事务的传播特性,如REQUIRED、SUPPORTS等,并展示了如何在XML配置中使用事务。
摘要由CSDN通过智能技术生成

一、java事务概述

1.1、java事务简述

1、简介
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列SQL操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行。如果任何一个SQL操作失败,那么整个操作就都失败,所有操作都会回滚到操作前状态,或者是上一个节点。

2、java事务和数据库事务的关联
实际上,一个Java应用系统,如果要操作数据库,则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的,事务的控制也相应转移到Java程序代码中。因此,数据库操作的事务习惯上就称为Java事务。

1.2、Java事务的类型

1、Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。
(1)JDBC事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手动提交。
使用 JDBC 事务界定时,可以将多个 SQL 语句结合到一个事务中。
特点:事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。
(2)JTA(Java Transaction API)事务允许程序执行分布式事务处理,使用此事务,需要一个实现javax.sql.XADataSource、javax.sql.XAConnection和javax.sql.XAResource接口的JDBC驱动程序,一个XADataSource对象就是一个XAConnection对象的工厂,XAConnections是参与JTA事务的JDBC连接,对于XA的连接不能调用java.sql.Connection.commit()或者java.sql.Connection.rollback()
而是应该调用UserTransaction.begin()、UserTransaction.commit()和
UserTransaction.rollback()。
特点:可以跨越多个数据库,功能强大,使用复杂
(3)容器事务
容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。

2、三种Java事务差异
(1)JDBC事务控制的局限性是在一个数据库连接内,但其使用简单。
(2)JTA事务的功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。
(3)容器事务,主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。

3、总结
Java事务控制是构建应用不可缺少的一部分,合理选择使用何种事务对整个应用系统来说至关重要。一般说来,在单个JDBC连接的情况下可以选择JDBC事务,在跨多个连接或者数据库情况下,需要选择使用JTA事务,如果用到了EJB,则可以考虑使用EJB容器事务

1.3、java事务的特性

事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性 (isolation)和持久性(durability)的缩写。
1、原子性(Atomicity):
事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。
2、一致性(Consistency):
当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。
3、隔离性(Isolation):
对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖 于或影响其他事务。
4、持久性(Durability):
事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的持久性。

通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行。

1.4、java事务的隔离级别

1、MySQL数据库为我们提供的四种隔离级别:
(1)Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
(2)Repeatable read (可重复读):可避免脏读、不可重复读的发生。
(3)Read committed (读已提交):可避免脏读的发生。
(4)Read uncommitted (读未提交):最低级别,任何情况都无法保证。

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。
  在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

2、脏读、幻读和不可重复读——简述
(1)脏读:一个事务读取到了另外一个事务没有提交的数据;
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
(2)不可重复读:在同一事务中,两次读取同一数据,得到内容不同;
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据,并且进行了修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)
(3)幻读:同一事务中,用同样的操作读取两次,得到的记录数不相同;
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

3、脏读、幻读和不可重复读——解决方案
(1)脏读:修改时加排他锁,直到事务提交后才释放,读取时加共享锁,读取完释放事务1读取数据时加上共享锁后(这 样在事务1读取数据的过程中,其他事务就不会修改该数据),不允许任何事物操作该数据,只能读取,之后1如果有更新操作,那么会转换为排他锁,其他事务更 无权参与进来读写,这样就防止了脏读问题。
但是当事务1读取数据过程中,有可能其他事务也读取了该数据,读取完毕后共享锁释放,此时事务1修改数据,修改 完毕提交事务,其他事务再次读取数据时候发现数据不一致,就会出现不可重复读问题,所以这样不能够避免不可重复读问题。
(2)不可重复读:读取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁。读取时候不允许其他事物修改该数据,不管数据在事务过程中读取多少次,数据都是一致的,避免了不可重复读问题
(3)幻读问题:采用的是范围锁RangeS RangeS_S模式,锁定检索范围为只读,这样就避免了幻读问题。

4、在MySQL数据库中查看当前事务的隔离级别:
select @@tx_isolation;
在MySQL数据库中设置事务的隔离 级别:
set [glogal | session] transaction isolation level 隔离级别名称;
set tx_isolation=’隔离级别名称;’
例1:查看当前事务的隔离级别:
在这里插入图片描述
例2:将事务的隔离级别设置为Read uncommitted级别:
在这里插入图片描述或:
在这里插入图片描述

1.5、spring事务的传播特性

1、spring事务的传播特性——简述
在这里插入图片描述

spring事务传播特性共分为7种,默认的是REQUIRED
REQUIRED (propagation_required)--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS(propagation_supports)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值