何为数据库事务

  “一荣共荣,一损共损”这句话很能体现事务的思想,很多复杂的事务要分步进行,但它们组成了一个整体,要么整体生效,要么整体失效。这种思想反映到数据库上,就是多条SQL语句,要么全部成功,要么全部失败。例如转账就可以看做一个事务,假设A要给B转账100元,在事务开始后,A的账户减少了100元, 假设在给B的账户转账时失败了,这时A账户已经减少了100元,B的账户也没有增加100元,这时A的账户应该回滚到事务开始之前的状态,而不是凭空少了100元。

  数据库事务有严格的定义,必须同时满足四个特效:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durabiliy),简称为ACID。

  • 原子性:表示组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作执行成功,整个事务才提交。事务中的任何一个数据库操作失败时,已经执行的任何操作都必须撤销,让数据库返回到初始状态。
  • 一致性:事务操作成功后,数据库所处的状态和它的业务规则是一直的,即数据不会被破坏。如A转账100元到B,不管操作是否成功,AB两个账户的存款总额应该不变。
  • 隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确的说,并非要求做到完全无干扰。数据库规定了多种事务隔离级别,不同的隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,并发性越弱。
  • 持久性:一旦事务提交后,事务中所有的数据操作都必须被持久化到数据库中。

  在这些事务特性中,数据“一致性”是最终目标。

  数据库管理系统一般采用重执行日志来保证原子性、一致性和持久性。重执行日志记录了数据库变化的每一个动作,数据库在一个事务中执行一部分操作后发生错误退出,数据库即可根据重执行日志撤销已经执行的操作。此外,对于已经提交的事务,既是数据库崩溃,在重启数据库时也能根据日志对尚未持久化的数据进行相应的重执行操作。

  和Java程序采用对象锁机制进行线程同步类似,数据库管理系统采用数据库锁机制保证事务的隔离性。当多个事务试图对相同的数据进行操作时,只有持有锁的事务才能操作数据,直到前一个事务完成后,后面的事务才有机会对数据进行操作。


数据并发问题

  一个数据库可能拥有多个访问客户端,这些客户端都可用并发的方式访问数据库。数据库中的相同数据可能同时被多个事务访问,如果没有采取隔离措施,就会导致各种并发问题,破坏数据的完整性。这些问题可归结为5类,包括3类数据度问题(脏读、不可重读和幻象读)及2类数据更新问题(第一类丢失更新和第二类丢失更新)。

  

数据库锁机制和事务隔离级别

  数据库通过锁机制解决并发访问问题,按锁定的对象不同,一般可以分为表锁定和行锁定。前者对整张表进行锁定,而后者对表中特定的行进行锁定。从并发事务锁定的关系上看,可以分为共享锁定和独占锁定。

  直接使用锁管理是很麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加合适的锁。此外,数据库也会维护这些锁,当一个资源上锁数目过多时,自动进行锁升级以提高系统的运行性能。

JDBC对事务的支持

  Connection默认情况下是自动提交的,即每条执行的SQL语句都对应一个事务。为了将多条SQL语句当成一个事务执行,必须先通过Connection#setAutoCommit(false)阻止Connection自动提交,再通过setTransactionIsolation()方法设置事务的隔离级别。

Spring学习记录5——数据库事务基础知识的更多相关文章

  1. 事务基础知识-->Spring事务管理

    Spring虽然提供了灵活方便的事务管理功能,但这些功能都是基于底层数据库本身的事务处理机制工作的.要深入了解Spring的事务管理和配置,有必要先对数据库事务的基础知识进行学习. 何为数据库事务 “ ...

  2. 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用

    在花了不少时间研究学习了MongoDB数据库的相关知识,以及利用C#对MongoDB数据库的封装.测试应用后,决定花一些时间来总结一下最近的研究心得,把这个数据库的应用单独作为一个系列来介绍,希望从各 ...

  3. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  4. 我的Spring学习记录(五)

    在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...

  5. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

  6. 学习 shell脚本之前的基础知识

    转载自:http://www.92csz.com/study/linux/12.htm  学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...

  7. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  8. Spring 学习记录3 ConversionService

    ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...

  9. Spring 学习记录8 初识XmlWebApplicationContext(2)

    主题 接上文Spring 学习记录7 初识XmlWebApplicationContext refresh方法 refresh方法是定义在父类AbstractApplicationContext中的. ...

随机推荐

  1. Git篇

    安装之后第一步 安装 Git 之后,你要做的第一件事情就是去配置你的名字和邮箱,因为每一次提交都需要这些信息: git config --global user.name "bukas&qu ...

  2. 京东基于Spark的风控系统架构实践和技术细节

    京东基于Spark的风控系统架构实践和技术细节 时间 2016-06-02 09:36:32  炼数成金 原文  http://www.dataguru.cn/article-9419-1.html ...

  3. Django入门9--Django shell

  4. 51nod1370 排列与操作

    性质:最终值域相同的一定是连续一段 花费最小?一定是值域个数个!并且当最后为i的数恰好只有i一个位置的时候,肯定选择不动,少花费一个 所以,我们考虑:每个最终方案在花费最小的方案下恰好被统计一次! 而 ...

  5. 21个项目玩转深度学习:基于TensorFlow的实践详解02—CIFAR10图像识别

    cifar10数据集 CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集.一共包含 10 个类别的 ...

  6. 2018-3-31-C#-谁改了我的代码

    title author date CreateTime categories C# 谁改了我的代码 lindexi 2018-3-31 21:15:3 +0800 2018-2-13 17:23:3 ...

  7. Mail.Ru Cup 2018 Round 2 C. Lucky Days(拓展欧几里得)

    传送门 待参考资料: [1]:https://www.cnblogs.com/Patt/p/9941200.html •题意 a君,b君存在幸运周期: a君在第[ L1+k·t1,R1+k·t1]天为 ...

  8. tab选项卡平滑滚动vue

    <html lang="en"> <head> <meta charset="UTF-8"> <title>Ti ...

  9. Javascript中数组方法reduce的妙用之处

    Javascript数组方法中,相比map.filter.forEach等常用的迭代方法,reduce常常被我们所忽略,今天一起来探究一下reduce在我们实战开发当中,能有哪些妙用之处,下面从red ...

  10. phpcms V9自定义分页函数

    大家做网站的时候,可能很多时候分页样式都得根据模板的要求来控制的,这时很多人都会去修改全局文件phpcms\libs\functions\global.func.php里的pages()函数,这样问题 ...