事务基础知识

数据库事务

数据库事务定义,满足4个特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),简称ACID。

  • 原子性:表示组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作都执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回到初始状态。

  • 一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏。如从A账户转账100元到B账户,不管操作成功与否,A和B的存款总额是不变的。

  • 隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确地说,并非要求做到完全无干扰,数据库规了多种事务隔离级别,不同隔离级别对应不同的干扰程序,隔离级别越高,数据一致性越好,但并发性越弱。

  • 持久性:一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须保证能够通过某种机制恢复数据。

数据库并发的问题

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

脏读(dirty read)
A事务读取B事务尚未提交的数据,并在这个数据的基础上操作。如果恰巧B事务回滚,那么A事务读到的数据根本是不被承认的。

时间转账事务A取款事务B
T1开始事务
T2开始事务
T3查询账户余额为1000元
T4取出500元,把余额修改为500元
T5查询账户余额为500元(脏读)
T6撤销事务余额恢复为1000元
T7汇入100元把余额改为600元
T8提交事务

不可重复读(unrepeatable read)
不可重复读是指A事务读取了B事务已经提交的更改数据。假设A在取款事务的过程中,B往该账户转账100元,A两次读取的账户的余额发生不一致:

时间取款事务A取款事务B
T1开始事务
T2开始事务
T3查询账户余额为1000元
T4查询账户余额为1000元
T5取出100元把余额修改为900元
T6提交事务
T7查询账户余额为900元,与T4读取的不一致

幻象读(phantom read)
A事务读取B事务提交的新增数据,这时A事务将出现幻象读的问题。幻象读一般发生在计算统计数据的事务中

时间统计金额事务A转账事务B
T1开始事务
T2开始事务
T3统计总存款数为1000元
T4新增一个存款账户,存款为100元
T5提交事务
T6再次统计总存款数为1100元,幻象读

幻象读和不可重复读是两个容易混淆的概念,幻象读是指读到了其他已经提交事务的新增数据,不可重复读是指读到了已经提交事务的更改数据(更改或删除),为了避免这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增加的数据,则往往需要添加表级锁——将整个表锁定,防止新增数据。

第一类丢失更新
A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能千万很严重的问题

时间取款事务A转账事务B
T1开始事务
T2开始事务
T3查询账户余额为1000元
T4查询账户余额为1000元
T5汇入100元,把余额修改为1100元
T6提交事务
T7取出100元,把余额改为900元
T8撤销事务
T9余额恢复为1000元(丢失更新)

第二类丢失更新
A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失

时间取款事务A转账事务B
T1开始事务
T2开始事务
T3查询账户余额为1000元
T4查询账户余额为1000元
T5汇入100元,把余额修改为1100元
T6提交事务
T7取出100元,把余额改为900元
T8提交事务(丢失更新)

ThreadLocal,它不是一个线程,而是线程的一个本地化对象。当工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。
ThreadLocal是如何做到为每一个线程维护一份独立的变量副本呢?思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。

数据库锁机制

按锁定的对象的不同,一般可以分为表锁定和行锁定,前者对整个表进行锁定,而后者对表中特定的行进行锁定。从并发事务锁定的关系上看,可以分为共享锁定和独占锁定。共享锁定会防止独占锁定,但允许其他的共享锁定。而独占锁定既防止其他的独占锁定,也防止其他的共享锁定。为了更改数据,数据库必须在进行更改的行上施加行独占锁定。

事务隔离级别

隔离级别脏读不可重复读幻象读第一类丢失更新第二类丢失更新
READ UNCOMMITED允许允许允许不允许允许
READ COMMITED不允许允许允许不允许允许
REPEATABLE READ不允许不允许允许不允许不允许
SERIALIZABLE不允许不允许不允许不允许不允许
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值