数据库事务

数据安全问题:脏读、不可重复读、幻读(都是多个事务同时执行时才发生)

1. 事务的定义

事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败
以下几个都可以看作一个事务:
* 查询一个用户的信息(select)
* 修改一个用户的年龄(update)
* 两个账户之间的转账(多个update)
* 删除一个用户(delete)
...

2. 事务的特性

原子性:事务是一个不可分割的单位,事务中的操作要么都发生,要么都不发生
一致性:事务前后数据的完整性必须保持一致
隔离性:多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离
持久性:事务一旦被提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应对其有任何影响

3. 事务的隔离级别

先了解并行度的概念:多个操作并发执行的程度。并行度越高,出现的问题也越多。
一般有四种:读读并行、读写并行、写读并行、写写并行。

SQL 92标准将事务的隔离级别定为4种
隔离级别含义并行度说明
READ_UNCOMMITED允许读取其他事务还未提交的数据读读并行、读写并行、写读并行因为写读并行,所以会出现脏读
READ_COMMITED允许读取其他事务提交后的数据读读并行、读写并行因为读写并行,所以会出现不可重复读。
REPEATABLE_READ可重复读读锁不能被写锁升级、读读可并行因为读使用的是行锁(猜的),未锁定新增加的行,所以会出现幻读
SERIALIZABLE序列化排他锁跟单线程一样执行,不存在多线程的问题

后来又出现一种新的隔离级别:SNAPSHOT ISOLATION。
SNAPSHOT ISOLATION:快照隔离级别。使用MVCC(多版本并发控制)。核心:copy on write,无锁编程。
针对读多写少场景优化(因为‘写’需要记录各个版本)
并行度可以做到:读读并行、读写并行、写读并行。这与READ_UNCOMMITED是相同的,但不会出现脏读、不可重复读。

 脏读不可重复读幻读
READ_UNCOMMITEDooo
READ_COMMITEDxoo
REPEATABLE_READxxo
SNAPSHOT
xxo
SERIALIZABLExxx

4. 事务的传播行为

假设有两个方法methodA()、methodB(),都使用了事务,而且methodA()调用了methodB()。问题:methodB()是否要作为methodA()事务的一部分提交?

java代码如下:

@Transactional
public void methodA() {
    methodB();
}
@Transactional
public void methodB() {
    // doSomething
}

为解决这个问题,spring提供了七种事务的传播行为

事务传播行为说明

PROPAGATION_REQUIRED

支持当前事务,如果不存在,就新建一个

PROPAGATION_SUPPORTS

支持当前事务,如果不存在,就不使用事务

PROPAGATION_MANDATORY

支持当前事务,如果不存在,抛出异常

PROPAGATION_REQUIRES_NEW

如果有事务存在,挂起当前事务,创建一个新事务

PROPAGATION_NOT_SUPPORTED

以非事务方式运行,如果有事务存在,挂起当前事务

PROPAGATION_NEVER

以非事务方式运行,如果有事务存在,抛出异常

PROPAGATION_NESTED

如果有事务存在,则嵌套事务运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值