简单理解数据库事务

数据库事务

为一个逻辑单元执行一系列的操作,要么完全执行,要么完全不执行。

事务可以确保非事务性单元内所有操作都可以完成,如果又失败的那么就不会永久的更新数据。

要满足一个事务必须要满足ACID(原子性、一致性、隔离性、持久性)

原子性(Atomic)

事务必须是原子工作单元:对于其数据修改,要没全执行要么都都不执行。通常来说一个事务内的多个操作时有共同目的的,并且时相互依赖。如果只执行其中一个那么就会达不到我们所要的目标。

默认情况下执行一条sql就是一个单独的事务,事务是自动提交的。我们要显示的使用的话,应该使用start transaction 来开启一个事务。

那数据库是怎么做到的呢,许多数据库采用的是日志机制,首先我们在提交事务的时候先把事务写在日志上。如果出现问题从日志上恢复。(我猜的。。。)

一致性 (consistent)

事务在完成时,必须使所有数据都保持一致状态。也就是说一个事务执行之前喝执行之后都应该保持一致性状态。银行转帐的例子:一共1000元,不管转几次总和都应该时1000元。满足完整性的约束条件。

怎么做到的:

  1. 数据库机制层面
    在一个事务执行之前和执行之后,数据会符合你设置的约束(唯一约束、外键约束、Check 约束等)和触发器设置。
  2. 业务层面
    对于业务层面来说就是保持业务等一致性,就比如上面钱的总和要一致。

隔离性(insulation)

在并发操作情况下,事务所做的修改必须要与其他事务隔离开。事务查看数据时的状态要么是个另一个并发事务修改之前的状态,要么时另一个事务修改之后的状态,事务不会查看中间状态的数据。

我们可以想下我们要达到这种效果一般,对于两个并发的事务A1 A2 在事务A1看起来,A2要要么时在A1没开始之前就已经执行结束,要么就是在已经执行之后在开始执行。这样每个事务就不会感觉到其他事务在并发的执行。这种完全隔离就会使得变成了串行执行。

一般情况下我们都会降低隔离级别来换取更大的吞吐量。

持久性(Duration)

事务执行完成后,它对于系统的影响时永久性的。即便时在数据库出现故障的时候也不会丢失事务的操作。

具体数据库是怎么做到的呢,事务中对数据库的修改会在写入数据之前先写入到事务日志中(和原子性差不多),然后事务日志按照顺序排好,当数据库朋克或者是服务器当掉了在重新启动数据库的时候会把事务日志中本应该执行的执行到数据库中。

事务之间的相互影响

由于完全的隔离性是不现实的,所以在数据不能保证隔离性的时候我们数据库会发生什么样的问题:

脏读

脏读是指在一个事务处理过程中读取了另外一个没有提交的事务中的数据。这样会造成很多不准确的问题。一个最典型的是:在一个事务回滚了的情况。比如:

update account set money=money+100 where name="张三"

update account set money=money-100 where name="李四"

在执行完第一条的时候,还没提及的时候,李四通知张三我已经转钱了,张三这时如果能查看到确实已经转过来了,然后就把李四的钱先扣了,但是后面又回滚了,这时候张三的钱并没有增长100。

不可重复读

不可重复读是指在一个事务中我们多次查询一个值却得到了不同的结果。这时由于在一个事务中被另一个事务提交并修改了。

其实在很多情况下不可重复读并不是问题,因为我们在多个查询某个数据的时候默认的是以最后查询到的结果为主。

幻读

幻读是事务非独立执行时发生的一种现象。当一个事务对全表的某一项做修改的操作,如果在这中间的时候,另外一个事务插入了一行新的数据,而这个数据是事务1要修改的值,在事务1执行完成查看的时候会发现我怎么有一个没有更改成功。就产生了幻觉。

比较:
幻读和不可重复读都是读取了一条已经提交完成的事务,而脏读则是读取了一条还没有提交的事务所修改过的数据。幻读和不可重复读懂区别就是不可重复读是针对的一条数据单个的别的事务提交的数据,而幻读则是针对的是一批数据

丢失更新

两个事务同时读取同一条记录,A先修改,B也修改,B并不知道A修改过,则B提交的数据就覆盖了A修改的结果。

隔离级别

针对上面会出现的情况,我们提供了四种隔离级别:

  1. Serializable (串行化):最高级别,可以避免上面的所有情况。以锁表的方式,使得其他事务职能在锁外等着,效率很低
  2. Repeatable read (可重复读):可以避免脏读、不可重复读 、丢失更新
  3. Read commited (已提交读):可以避免脏读
  4. Read Uncommited(未提交读):啥都避免不了

在mysql中默认的隔离级别是 可重复读,我们可以使用select @@tx_isolation;来查看当前事务的隔离级别。然后我们使用set [global | session] transaction isolation level 隔离级别名称

如果要是使用的是JDBC,那么每次设置只是在当前session中有效,对其他的session中是无效的。

具体着几种级别是怎么实现和区分的:是使用不同的锁来实现的。

  1. 未提交读:在读数据时不会检查和使用任何锁。所以可以得到没有提交的数据
  2. 已提交读:只读取提交读数据,等待其他事务释放排他锁,也就是说当前事务会被其他事务的排他锁所阻塞。读数据时产生的共享锁会在读操作结束完立即释放,不会等到事务结束的时候释放
  3. 可重复读:保持共享锁一致到事务结束
  4. 可串性读:工作方式类似于可重复读,但它相当于不是行级锁,是页级锁或者是表锁,会组织查询新插入读所涉及到的范围
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容