数据库事务详解

2020-03-11  本文已影响0人  末池桑

事务概念

事务在数据库里是很重要的概念,指的是用户定义的一组不可分割的数据库操作序列,这组操作要么全执行,要么全失败回滚,保证了数据操作前后持一致性。以 JDBC 操作数据库中的转账汇款为例,在没开启事务的情况下,假设 xm、xh各有 1000 块钱,总共 2000 块钱,当 xm 向 xh 汇款 100 块钱时,执行如下图的方法:

xm 账户先是减去了相应的 100 ,但是由于 /by zero 异常,xh 账户上却没有加上相应的 100,此时就是丢掉了数据前后的一致性,因为当上图 transfer 方法执行后,xm 还有 900,xh 还是 1000 块钱,总共 1900 块钱,与刚开始 xm、xh 共持有的钱 2000 不符,也就是 xm 平白无故的就消失了 100 块钱,这个要是在现实生活中换做谁都是接收不了的。

而事务开启后,上图中这两条 sql 语句将会变成一荣俱荣,一损俱损的状态(原子性),只要事务还没提交,即使发生了 /by zero 错误,xm 减去 100 的那条 sql 语句就会被回滚,xm 最终还是 1000 块钱,从而保证了 xm、xh 所持有总钱数的一致性。

四大特性(ACID)

事务并发问题

当多个事务并发访问数据时,若不对并发操作加以控制的话,就可能会造成查询和更新到不正确的数据,破坏事务前后的一致性,发生脏读、不可重复读、虚读。

事务 B 先查询了 xm 的 money,接着事务 A 修改了 xm 的 money ,A 并没有提交事务,事务 B 再次查询 xm 的 money 时就变为了事务 A 修改后的内容了,这个就是脏读。

意思是指:事务 A 在 update 一行数据的时候,事务 B 在其 update 前后都访问了这行数据,导致事务 B 两次查询这行数据时结果不一致。注:这里是指 update 一行数据,与幻读中的 insert 数据不同。

这个和不可重复读的概念很像,在事务 B insert 一行数据时,事务 A 在 insert 之前查了两次表中所有数据,导致两次结果集不一致,第二次查询时多了一条事务 B insert 的数据。注:这里是指 insert 一行数据,与幻读中的 update 数据不同。

MySQL 事务隔离级别

事务隔离级别是事务并发控制的整体解决方案,它通过锁机制来实现的,MySQL 有四个隔离级别,通过设置相应隔离级别可以防止脏读、不可重复读、幻读。

MySQL 查看隔离级别: select @@session.tx_isolation, @@global.tx_isolation; (session / local 为会话变量,global 为全局变量)
MySQL 设置隔离级别:set @@session.tx_isolation = 0/1/2/3;(0~3 分别表示:Read uncommitted 、Read committed、Repeatable read 、Serializable)

上一篇 下一篇

猜你喜欢

热点阅读