java事务总述

article/2025/10/3 3:55:33

文章目录

  • 一、java事务概述
    • 1.1、java事务简述
    • 1.2、Java事务的类型
    • 1.3、java事务的特性
    • 1.4、java事务的隔离级别
    • 1.5、spring事务的传播特性
    • 1.6、spring支持的事务管理类型
  • 二、java事物使用
    • 2.1、XML配置
    • 2.2、事务使用方式

一、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)--支持当前事务,如果当前没有事务,就以非事务方式执行。
REQUIRES_NEW(propagation_requires_new)--新建事务,如果当前存在事务,把当前事务挂起。
MANDATORY(propagation_mandatory)--支持当前事务,如果当前没有事务,就抛出异常。
NOT_SUPPORTED(propagation_not_support)--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER(propagation_never)--以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED(propagation_nested)--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作。

2、spring事务的传播特性——详解
(1)【REQUIRED】
service1:事务传播机制:REQUIRED
service2:事务传播机制:REQUIRED
REQUIRED:支持事务,没有事务时创建新的事务,如果存在事务则直接加入该事务执行
method1执行时没有事务,则会新建事务Tx1,在method1中调用method2时,发现已经存在事务,则会加入事务执行,最后执行commit

(2)【SUPPORTS】
如果其他bean调用这个方法时,其他bean声明了事务,则就用这个事务,如果没有声明事务,那就不用事务
service1:事务传播机制:REQUIRED
service2:事务传播机制:SUPPORTS
method1执行时没有事务,则会新建事务Tx1,method2执行时检查到存在事务,则在事务中进行执行,然后进行commit
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:SUPPORTS
method1执行不会创建事务,method2也不会创建事务
SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务

(3)【MANDATORY】
必须在一个已有的事务中执行,否则报错
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:MANDATORY
method1不会创建事务执行,method2执行时检查当前没有事务,则会抛出异常不会执行,method1已经在数据库层面执行成功并完成commit,所以抛出的异常不影响method1的执行结果
MANDATORY必须在已有事务下被调用,否则报错

(4)【REQUIRES_NEW】
REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务
service1:事务传播机制:REQUIRED,
service2:事务传播机制:REQUIRES_NEW
执行method1时会创建新的事务Tx1,执行method2时会先将Tx1挂起,然后创建新的事务Tx2,执行完后Tx2进行commit,然后将Tx1解除挂起,Tx1进行commit
REQUIRES_NEW为当前方法创建一个新的事务,并且当前事务先提交,然后再提交老的事务
新的事务提交成功之后,老的事务提交失败时新的事务的sql不会回滚
新的事务提交失败回滚,老的事务是否会进行回滚?应该会的

(5)【NOT_SUPPORTED】
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:REQUIRED
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起
method1执行不会创建事务,执行method2时会创建新的事务,执行sql之后会进行commit
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:NOT_SUPPORTED
两个方法都不会创建事务执行
NOT_SUPPORTED相当于没有Spring事务,每条执行语句单独执行,单独提交

(6)【NEVER】
须在一个没有事务中执行,否则报错
service1:事务传播机制:REQUIRED
service2:事务传播机制:NEVER
method1执行时没有事务,则会新建事务Tx1,method2执行时检查到存在事务,则会进行报错抛出异常,method1由于还没有提交事务,则会进行回滚

(7)【NESTED】
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作
service1:事务传播机制:REQUIRED
service2:事务传播机制:NESTED
method1执行时没有事务,则会新建事务Tx1,执行sql后不会提交,method2创建一个NESTED嵌套事务执行sql,然后一起提交
method1方法创建一个事务,则再调用method2方法时,直接在该事务的基础上创建一个嵌套事务,本质上还是同一个事务,做一次提交;
service1:事务传播机制:NOT_SUPPORTED
service2:事务传播机制:NESTED
method1执行不会创建事务,sql执行在数据库commit,method2会创建一个事务执行sql后commit
method1方法不创建事务,则调用method2方法时,直接创建一个新的事务,单独提交
用法:

@Transactional(propagation = Propagation.REQUIRED)
public void transcationTest(){
.....
}

用注解的方式添加事务时,类内部调用带有注解的方法,事务不生效。注解的事务使用aop切入上的。
可以注入当前类,调用类下的方法。

1.6、spring支持的事务管理类型

1、事务管理类型
编程式事务管理:可以通过编程的方式控制事务的开启、提交和回滚。(灵活性高,很难维护)——jdbc事务
声明式事务管理:可以将业务代码和事务管理分离,只需用注扇子和XML配置来管理事务。——JTA事务

2、声明式事务管理
(1)基于接口
a、基于TransactionInterceptor的声明式事:
Spring 声明式事务的基础,通常也不建议使用这种方式,但是与 aop 一样,了解这种方式对理解 Spring 声明式事务有很大作用。
b、基于 TransactionProxyFactoryBean 的声明式事务:
第一种方式的改进版本,简化的配置文件的书写,这是 Spring 早期推荐的声明式事务管理方式。
(2)、基于< tx >和< aop >命名空间的声明式事务管理:
目前推荐的方式,其最大特点是与 Spring AOP 结合紧密,可以充分利用切点表达式的强大支持,使得管理事务更加灵活
(3)、基于@ Transactional 的全注解方式:
将声明式事务管理简化到了极致。开发人员只需在配置文件中加上一行启用相关后处理 Bean 的配置,然后在需要实施事务管理的方法或者类上使用@ Transactional 指定事务规则即可实现事务管理,而且功能也不必其他方式逊色。

二、java事物使用

2.1、XML配置

1、配置事务管理器

 <!--事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>

2、配置事务开启方式
事务有三种开启方式:
(1) 代理工厂

    <!--第一种事务开启方式代理工厂--><bean id="txService"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager" ref="transactionManager"></property><property name="target" ref="stockpPayService"></property><property name="transactionAttributes"><props><prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop></props></property></bean>

(2)注解

<!--第二种事务开启方式,注解版-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
//后台方法代码上加此注解
@Transactional(rollbackFor = StockException.class)

(3)aspectj xml

    <!--第三种方式 aspectj xml版--><tx:advice id="txadvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="mypointccut" expression="execution(* *..day22tx.service.*.*(..))"></aop:pointcut><aop:advisor advice-ref="txadvice" pointcut-ref="mypointccut"></aop:advisor></aop:config>

2.2、事务使用方式

1、注解方式

股票交易的实现类StockPayServiceImplpackage cn.dawn.day22tx.service;import cn.dawn.day22tx.dao.IAccountDAO;
import cn.dawn.day22tx.dao.IStockDAO;
import cn.dawn.day22tx.entity.StockException;
import org.springframework.transaction.annotation.Transactional;/*** Created by Dawn on 2018/3/15.*/
public class StockPayServiceImpl implements IStockPayService {IStockDAO iStockDAO;IAccountDAO iAccountDAO;//注解使用事物@Transactional(rollbackFor = StockException.class)public boolean buyStock(int aid, int ablance, int sid, int scount) throws StockException {boolean isBuy=true;boolean sflag = iStockDAO.updateStock(sid, scount, isBuy);if(true){throw new StockException("网络被挂掉异常");}boolean aflag = iAccountDAO.updateAccount(aid, ablance, isBuy);if(sflag&&aflag)return true;elsereturn false;}public IStockDAO getiStockDAO() {return iStockDAO;}public void setiStockDAO(IStockDAO iStockDAO) {this.iStockDAO = iStockDAO;}public IAccountDAO getiAccountDAO() {return iAccountDAO;}public void setiAccountDAO(IAccountDAO iAccountDAO) {this.iAccountDAO = iAccountDAO;}
}

@Transactional里面只写了遇到什么异常会回滚,它的传播行为和隔离级别有默认值,就省略了

   StockExceptionpackage cn.dawn.day22tx.entity;/*** Created by Dawn on 2018/3/15.*/
public class StockException extends ClassNotFoundException {public StockException() {}public StockException(String s) {super(s);}
}

http://chatgpt.dhexx.cn/article/DqIJ48FD.shtml

相关文章

Java中的事务及使用

什么是事务&#xff1f; 事务&#xff08;Transaction&#xff09;&#xff0c;一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言&#xff08;如SQL&#xff0c;C或Java&am…

测试用例设计方法---等价类划分法

1 等价类划分法 1.1 定义 是把所有可能输入的数据&#xff0c;即程序的输入域划分策划国内若干部分&#xff08;子集&#xff09;&#xff0c;然后从每一个子集中选取少数具有代表性的数据作为测试用例。方法是一种重要的、常用的黑盒测试用例设计方法。 1.1划分等价类 1&a…

02测试用例设计方法-等价类划分

等价类划分法 1&#xff09;定义 是把所有可能的输入数据,即程序的输入域划分成若干部分&#xff08;子集&#xff09;,然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。使用这一方法时&#xff0c;完全不考虑程序的…

等价类划分用例案例设计

一、加法案例 测试要求&#xff1a;计算1到100的两个整数之和&#xff08;包括1和100&#xff09; 提示&#xff1a;一般是一个框输入正确的值&#xff0c;一个框输入错误的值&#xff0c;没有两个框都输入错误的值&#xff0c;因为更容易确定到底是哪个框出现错误的值&#x…

常见测试用例设计方法1---等价类划分

目录 一&#xff0c;等价类划分概念&#xff1a; 二&#xff0c;有效等价类和无效等价类&#xff1a; 三&#xff0c;划分等价类的标准 四&#xff0c;设计测试用例 五&#xff0c;以QQ密码设定规则为例使用等价类划分编写测试用例 1&#xff0c;分析需求&#xff0c;确定输…

黑盒测试方法|测试用例的设计方法--等价类划分方法

黑盒测试方法–测试用例的设计方法–等价类划分方法 目录 等价类划分方法边界值分析方法错误推测方法因果图方法判定表驱动分析方法正交实验设计方法功能图分析方法场景设计方法 等价类划分方法 一、方法简介 &#xff08;1&#xff09;定义 把所有可能的输入数据,即程序的…

软件测试:等价类划分举例

等价类的设计思路&#xff1a; 根据输入条件&#xff0c;确定等价类&#xff0c;包括有效等价类和无效等价类&#xff0c;建立等价类列表为每个等价类规定一个唯一的编号设计一个测试用例&#xff0c;使其尽可能多地覆盖尚未被覆盖的有效等价类&#xff0c;重复这一步&#xff…

等价类划分法-案例剖析-设计测试用例

目录 等价类划分法概念 有效等价类和无效等价类 等价类设计测试用例步骤 案例1 案例2 案例3 等价类划分法概念 等价类划分法是把所有可能的输入数据&#xff0c;即程序的输入数据集合划分成若干个子集即等价类&#xff0c;然后从每个等价类中选取少量具有代表性的数据作为…

15.3-等价类划分

目录 一、等价类划分的概念 二、使用等价类划分的原因 三、等价类划分的价值 四、相关概念 1、等价类 2、有效等价类 3、无效等价类 五、等价类划分法使用步骤 六、等价类的划分原则 1、原则1 2、原则2 3、原则3 4、原则4 5、原则5 6、原则6 七、测试用例的设计步骤 八、等价类…

软件测试用例设计 (一)等价类划分法

软件测试对于软件的重要性不言而喻&#xff0c;是计算机类学生毕业后的一个重要从业方向之一。 如果要从事软件测试&#xff0c;那么有些必备的技能还是要有的。比如&#xff0c;测试理论、测试工具、测试文档的编制。 今天我们就来看看最最最重要的测试理论&#xff1a;黑盒…

测试用例设计——等价类划分法

一、分析问题 如果我们需要对下面的这个两位数加法器设计测试用例&#xff0c;在测试了1&#xff0b;1&#xff0c;1&#xff0b;2&#xff0c;&#xff08;-1&#xff09;1和&#xff08;-1&#xff09;&#xff0b;2之后&#xff0c;是否有必要测试1&#xff0b;3&#xff0c…

等价类划分法设计用例(超详细)

等价类划分法 等价类&#xff1a; 1、解决了不能穷举测试的问题、控制成本、控制测试用例数量 2、数据值要明确&#xff0c;对文字敏感 3、依据需求将输入划分为若干个等价类&#xff0c;划分等价类&#xff08;需求、数据特征&#xff09; 等价类设计用例的难点&#xff1a;…

测试用例设计方法 之【等价类划分法】

前言&#xff1a; 在没有测试用例之前&#xff0c;团队里的成员进行测试时&#xff0c;完全“以人为本”&#xff0c;根据个人思路、需求理解度、发散性思想来完成测试系统&#xff0c;人无完人&#xff0c;弊端显而易见。衍生出【测试用例】后&#xff0c;测试工作的目标得到…

等价类划分法测试用例设计举例

一、基本概念 等价类是指程序输入域的子集。 等价类划分&#xff08;Equivalance Partitioning&#xff09;测试的思想&#xff1a;将程序的输入域划分为若干个区域&#xff08;等价类&#xff09;&#xff0c;并在每个等价类中选择一个具有代表性的元素生成测试用例。该方法…

等价类划分测试用例设计方法

一.方法简介 1.定义 是把所有可能的输入数据,即程序的输入域划分成若干部分&#xff08;子集&#xff09;,然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。 2.划分等价类 等价类是指某个输入域的子集合。在该子集合…

编写测试用例方法之等价类划分法

今天我们再来介绍另外一个编写测试用例的方法&#xff1a;等价类划分法&#xff0c;这个方法是最常用的写用例的方法。话不多说&#xff0c;开始整干货&#xff0c;首先&#xff0c;全图镇楼。 之前我们是如何测试一个商品的呢&#xff1f;产品就是要有它的测试点。测试点之前也…

等价类划分法设计测试用例

等价类划分法&#xff1a; 一、方法简介 1.定义 是把所有可能输入的数据&#xff0c;即程序的输入域划分策划国内若干部分&#xff08;子集&#xff09;&#xff0c;然后从每一个子集中选取少数具有代表性的数据作为测试用例。方法是一种重要的、常用的黑盒测试用例设计方法…

常用测试用例设计方法5-错误推算法

一&#xff0c;错误推算法的定义 基于测试人员的经验和直觉推测推测程序中所有可能存在的各种错误&#xff0c;有针对性的设计测试用例的方法。 二&#xff0c;错误推算法的基本思想 基于测试人员的经验和直觉推测推测程序中所有可能存在的各种错误&#xff0c;有针对性的设计…

测试用例设计--等价类的几个例子

等价类的设计思路: 根据输入条件,确定等价类,包括有效等价类和无效等价类,建立等价类列表为每个等价类规定一个唯一的编号设计一个测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类被覆盖完为止设计一个测试用例,使其尽可能多的覆盖…

理解:守护线程---理解

定义&#xff1a;守护线程--也称“服务线程”&#xff0c;在没有用户线程可服务时会自动离开。 优先级&#xff1a;守护线程的优先级比较低&#xff0c;用于为系统中的其它对象和线程提供服务。 设置&#xff1a;通过setDaemon(true)来设置线程为“守护线程”&#xff1b;将一…