关于数据库的事务

算法吟游者
• 阅读 1561

由于Mongodb不支持事务(老版本),自己在工作中也从来没有用过事务,今天在面试的时候提到类似这么一个问题:在数据库中要新增一条A记录,同时要修改B记录的一个字段,这个肯定是用事务实现,但是Mongodb不支持事务,你会怎么设计数据库的事务?

很尴尬,我不知道如何回答。

1.事务的用法

先来一段事务的使用方法(网上看到的,不保证正确性)

try {  
    conn.setAutoCommit(false);  //将自动提交设置为false  

    ps.executeUpdate("修改SQL"); //执行修改操作  

    ps.executeQuery("查询SQL");  //执行查询操作                 

    conn.commit();      //当两个操作成功后手动提交  

} catch (Exception e) {  

    conn.rollback();    //一旦其中一个操作出错都将回滚,使两个操作都不成功  

    e.printStackTrace();  
} 

由以上代码可以看出,将两个操作当作一个事务来执行,执行完毕后可以commit该事务,否则回滚该事务,不会对数据库中的数据产生任何影响。

2.事务的实现

事务有四大特性:ACID
以转账操作为例,A账户转账100元给B账户。
原子性:即两个操作要么都执行,要么都不产生效果,绝对不会产生A-B的中间状态。
一致性:即A账户减少了100元钱,B账户就一定增加了100元,否则就违背了一致性。
隔离性:两个事务之间的操作不应该互相影响。
持久性:数据库事务一旦提交,就不会再被修改。

问题一:原子性和一致性有什么区别?
从描述上来看,原子性保证所有操作必须执行或者都不产生效果,那么只有AB两个状态,即一致性的两种状态。
那为什么说原子性不能保证一致性呢?
因为事务1在执行的时候,事务2有可能会影响到事务1的中间状态,这就引入了隔离性。

问题二:怎么保证原子性?
先写日志,再改数据。
将所有对数据库的操作,都先通过记录日志的方式保存下来,当发生异常情况时,可以重放日志操作来撤销对数据库的修改。
日志记录完整,但再写数据库时异常,重启后这部分数据重放进入数据库。
日志记录异常,日志都不完整,重放时没有commit标记,不会进入数据库。

问题三:怎么保证一致性?
引入隔离性。

问题四:怎么保证隔离性?
各种锁。
悲观锁:
在一个事务未提交前,禁止另一个事务做修改,这样的话当然保证了独立性,但是性能会差。为了提高性能,引入了各种粒度的锁(数据库表级、行级、库级锁,各种性质的锁:排它锁,死锁问题:两阶段锁

乐观锁:
在比较晚提交的事务当中检测数据是否被修改,如果被修改了,就放弃本次提交。

参考文章:辨析ACID四种特性的关系

引用知乎--我练功发自内心
区别数据库、操作系统的原子性概念
作者:我练功发自真心
首先说对原子性的理解。数据库的理解和操作系统的理解是截然相反的。

数据库的原子性说的其实不是楼上说的那些。数据库的原子性说的是failure atomicity:一个事物要么运行成功,要么完全没有运行。也正如题主所问的(非常贴切!),这东西和一致性直接相关。因为如果一个事务的修改到一半终止掉,那么是不可能保持一致性的!

那么楼上说的是啥呢?楼上说的其实是操作系统对atomic的理解:并发控制。OK为啥这么说,因为操作系统直到现在都没有一个统一的并发控制体系,最常用的并发控制就是:锁。而且,锁在操作系统里是没法和数据进行对应的。所以,在操作系统里,用锁来控制运行的顺序:任何要看到非atomic的操作或者非consistent的线程和Interrupt handler都被锁锁在外面。所以,这是操作系统理解的一致性和原子性。

那么数据库说的一致性和原子性是怎么实现的呢?

一般来说用journaling。

任何的修改都先写在一个journal/log里。当事务提交时,会再写一个叫做commit record的东西。那么想象如下情况:如果断电发生,没有提交的事务完成了一半,这个事务就不会有commit record,那么在恢复的时候就会跳过这个事务,就当它没发生;如果提交的事务完成了,那么你一定会看到一个commit record,这时候你就可以根据journal里的数据来恢复你数据库的内容了,这时候,这个事务完整提交。

还有一个叫做copy on write/shadow paging的方法,一般不在数据库中用。因为数据库往往希望对连续读做优化。(但谁知道以后呢…)

PS 数据库的并发控制非常统一(isolation),楼上说了用锁做控制是比较传统的做法(2PL)。除此之外,还有著名的MVCC,比较激进的OCC方法等等…

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
PostgreSQL Freeze 风暴预测续
标签PostgreSQL,Freeze,风暴背景PostgreSQL目前默认的存储引擎,事务可见性需要依赖行头的事务号,因为事务号是32位的,会循环使用。在一条记录产生后,如果再次经历了20亿个事务,必须对其进行freeze,否则数据库会认为这条记录是未来事务产生的(可见性判断)。因此FREEZE操作是数据库在32
Wesley13 Wesley13
3年前
JDBC对事务的使用(包括自动提交,回滚等知识)
首先得清楚什么时候使用事务。当你需要一次执行多条SQL语句时,可以使用事务。通俗一点说,就是,如果这几条SQL语句全部执行成功,则才对数据库进行一次更新,如果有一条SQL语句执行失败,则这几条SQL语句全部不进行执行,这个时候需要用到事务。其次才是事务的具体使用。1.获取对数据库的连接(代码这里省略了吧,网上太多了,对各种数据库
Stella981 Stella981
3年前
Redis笔记总结
四、事务  Redis中的事务是一组命令的集合。事务同命令一样都是Redis的最小执行单位,一个事务的命令要么全部执行,要么全部不执行。  事务的原理是先将一个事务的命令发给Redis,然后再让Redis依次执行这些命令。  需要注意的是Redis并没有提过像关系型数据库那样的回滚功能!不过由于Redis不支持回滚,这也使得Redis在事
Stella981 Stella981
3年前
2019年JAVA面试题(高级资深)
记录下本年度最新的面试题:20190424//某互联网公司,劳工资源管理方向职位1.bio/nio/aio介绍下,粘包、拆包问题怎么解决?2.数据库四个特性是什么,事务传播性是怎么样的?spring事务和数据库事务的区别关系3.HashMap/concurrentHashMap区别和底层实现、TreeMap特点4.sql优化
可莉 可莉
3年前
2019年JAVA面试题(高级资深)
记录下本年度最新的面试题:20190424//某互联网公司,劳工资源管理方向职位1.bio/nio/aio介绍下,粘包、拆包问题怎么解决?2.数据库四个特性是什么,事务传播性是怎么样的?spring事务和数据库事务的区别关系3.HashMap/concurrentHashMap区别和底层实现、TreeMap特点4.sql优化
Wesley13 Wesley13
3年前
mysql的innodb中事务日志ib_logfile
mysql的innodb中事务日志ib\_logfile事务日志或称redo日志,在mysql中默认以ib\_logfile0,ib\_logfile1名称存在,可以手工修改参数,调节开启几组日志来服务于当前mysql数据库,mysql采用顺序,循环写方式,每开启一个事务时,会把一些相关信息记录事务日志中(记录对数据文件数据修改的物理位置或
Wesley13 Wesley13
3年前
Mysql系列第十五讲 事务详解
Mysql系列第十五讲什么是事务?事务的几个特性(ACID)Mysql中事务操作savepoint关键字只读事务事务中的一些问题事务的隔离级别关于隔离级别的选择什么是事务?数据库中的事务是指对数据库执行一批操作,这些操作最终要么
Wesley13 Wesley13
3年前
Mysql redo&&undo学习
   mysql通过锁机制来实现事务的隔离性,用redolog实现事务的原子性和持久性,用undolog实现事务的一致性。undo并不是redo的逆过程,redo和undo都可以看做一种恢复过程,redo恢复事务修改的页操作,redo记录的是物理日志,记录的是页的物理修改操作,redolog基本上都是顺序写的,在数据库运行时不需要对redolog
Wesley13 Wesley13
3年前
MySql学习18
本篇讲述数据库中非常重要的事务概念和如何使用MySQL命令行窗口来进行数据库的事务操作。下一篇会讲述如何使用JDBC进行数据库的事务操作。  事务是指数据库中的一组逻辑操作,这个操作的特点就是在该组逻辑中,所有的操作要么全部成功,要么全部失败。在各个数据具有特别紧密的联系时,最好是使用数据库的事务来完成逻辑处理。  例如路人甲A给路人甲B转账
Wesley13 Wesley13
3年前
MySQL常见问题
事务四大特性原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
Wesley13 Wesley13
3年前
Mysql事务,并发问题,锁机制
1、什么是事务事务是一条或多条数据库操作语句的组合,具备ACID,4个特点。原子性:要不全部成功,要不全部撤销隔离性:事务之间相互独立,互不干扰一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏持久性:事务的提交结果,将持久保存在数据库中2、事务并发会产生什么问题1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时