[JAVA]JDBC事务管理方式

ops/2024/10/30 23:19:33/

     本节我们要学习在JDBC中如何对数据库的事务进行管理,举一个生活中的例子,我们的小伙伴小红最近资金紧缺,钱包没有余额,小红便向小明借钱。于是小明很大方的借给小红100块钱,此时,小明的钱包余额便会减少100元,而对应的小红余额便会多出100元,这是生活中再常见不过的例子。 

     如果放在数据库中来说,我们必须要保证小明的账户减少100元后,小红的账户便会多出100元,而绝不允许出现小明的账户减少100元后,小红的账户没有任何变化。

     那么我们如何保证在小明的账户少了100元后,小红的账户必然会加100元?这里就要用到我们的数据库事务机制

什么是事务?

     事务是以一种可靠的,一致的方式,访问和操作数据库的程序单元(说人话:要么把事情做完,要么什么都不做,不要做一半)。

事务是依赖于数据库实现,MySQL通过事务区作为数据缓冲地带。

                                        事务的提交操作

     以上图是Java中的JDBC应用程序 远程操作 数据表,在MySQL中因为有事务区的存在,所以JDBC应用程序写入数据时,并不是直接把数据放到数据表中,而是先把它放到事务区里。

     如果数据很小的情况下,这个事务区中的数据放在内存中加快处理数据,但如果事务区比较大的时候,它往往会写入到硬盘,用一块硬盘空间作为事务的缓冲。

     我们知道小红找小明借钱,这属于两条数据的更新操作,小明的数据减去100元,而小红的数据加上100元,演示在MySQL中如何处理这种描述。

程序先对小明的余额进行减法操作,再对小红的余额做加法操作,但不会直接将更新后的操作给数据表,而是先把中间结果放到事务区(写操作)。

当程序对这两个更新操作全部执行完之后,会主动的向MySQL发起commit提交命令,这个commit提交会直接作用在MySQL事务区上(commit提交)。

MySQL收到commit提交,于是事务区会将已加减的数据操作一次性的写入到我们的数据表中(写入)

      在我们进行数据的写操作时,两次的数据更新都是面向事务区的,只有进行commit提交时,才由事务区真正的写入到数据表中。当写入成功后,事务区中的数据自然就无意义了,所以由MySQL自动的将数据清空,等待下一次应用程序再向事务区中进行新数据的写入。

 这就是我们事务的提交操作。

                                         事务的回滚操作

      出现事务回滚操作的情况:假设,我们应用程序第一次对小明的余额进行减100操作时,操作能正常执行,但由于某种原因,在对小红余额进行加100操作时,程序报错了。  我们的JDBC应用程序会向事务区发送一个rollback回滚命令,这会使的已经在事务区中已处理过的小明账户减法操作给清空。

      也就是指,当我们的应用程序一旦向事务区提交了rollback指令以后,无论我们之前做了多少数据的前置处理,都会将事务区的数据清空。最终数据表中不会产生任何写入的实质操作 。

       总结来说:作为事务来说,要么一次性全部完成,要么将之前所有已经处理过的数据通过rollback回滚全部撤销(遇到程序错误的情况下)。

       应用程序主要控制commit和rollback回滚,只有应用程序发起这样的命令,MySQL才能执行对应的操作。

JDBC允许两种事务模式

  • 自动提交事务模式
  • 手动提交事务模式

1.自动提交事务模式

  • 自动提交模式是指每执行一次写操作,SQL自动提交事务
  • 自动提交开启方法:conn.setAutoCommit(true)
  • 自动事务是JDBC默认行为,此模式无法保证多数据一致性

 注:自动提交模式有很大的局限性,因为每一次执行写操作以后,它都会立即提交,无法保障数据的一致性。

 2.手动提交事务模式

  • 手动提交模式是指显式调用commit()与rollback()方法管理事务
  • 手动提交开启方法:conn.setAutoCommit(false)
  • 手动提交事务可保证多数据一致性,但必须手动调用提交/回滚方法

那么如何手动提交事务模式呢?让我们在下一章学习


http://www.ppmy.cn/ops/129395.html

相关文章

bluez hid host介绍,连接键盘/鼠标/手柄不是梦,安排

零. 前言 由于Bluez的介绍文档有限,以及对Linux 系统/驱动概念、D-Bus 通信和蓝牙协议都有要求,加上网络上其实没有一个完整的介绍Bluez系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度,学习曲线也相对较陡,所以我有了这个想法,专门对Bluez做一个系统…

66Analytics 汉化版,网站统计分析源码,汉化前台后台

66Analytics 汉化版,网站统计分析源码,汉化前台后台 本源码汉化前台后台,非其他只汉化前台版 网络分析变得容易。自托管、友好、一体化的网络分析工具。轻量级跟踪、会话回放、热图、用户旅程等 简单、好看、友好-大多数网络分析解决方案做得太多了,在大…

泛型的特点

在 Java SE 1.5 之后,泛型(Generics)作为一项重要的语言特性被引入。泛型让开发者可以编写更通用、类型安全的代码,并允许在编译时进行类型检查,从而减少运行时错误。正如《Java 核心技术》中的定义:“泛型…

Java三大特性之封装

封装是Java三大特性之一,它是指将数据和方法捆绑在一起的机制。封装可通过将数据和方法封装在类中来实现。 封装的目的是将类的实现细节隐藏起来,只暴露必要的接口给外部使用。这样做的好处有: 数据的隐藏:封装可以隐藏类的内部实…

如何批量注册多个Outlook邮箱账号并避免关联

批量注册多个Outlook邮箱账号时,如何避免账号之间的关联性是一个重要的考量因素。会在此文一起探讨如何高效且安全地批量注册多个Outlook邮箱账号,并提供一些实用的建议来确保这些账号不会被关联。 一、Outlook邮箱批量注册机制 在深入注册流程之前&…

JS轮播图实现自动轮播、悬浮停止轮播、点击切换,下方指示器与图片联动效果

代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

python 跳过当前循环

在 Python 中&#xff0c;可以使用 continue 语句来跳过当前循环的剩余部分&#xff0c;并继续下一次循环。continue 语句用于跳过循环体中剩余的语句&#xff0c;并立即开始下一次迭代。 以下是一个简单的示例&#xff0c;演示了如何在 for 循环中使用 continue 语句&#xf…

批处理操作的优化

原来的代码 Override Transactional(rollbackFor Exception.class) public void batchAddQuestionsToBank(List<Long> questionIdList, Long questionBankId, User loginUser) {// 参数校验ThrowUtils.throwIf(CollUtil.isEmpty(questionIdList), ErrorCode.PARAMS_ERR…