事务的隔离级别 另一种事务开启方式

事务是有隔离级别

read uncommited (读未提交):不做任何隔离,具有脏读,不可重读对,幻读的问题

read committed (读提交):可以防止脏读,不能防止不可重复读和幻读的问题

repeated read(可重复读):可以防止脏读,不可重复读,不能放在幻读(mysql的默认隔离级别)

serializable(串行化):数据库运行为串行,以上问题都可以防止,但是性能低

下面的解释都用这个user表

脏读(a,b同时开始事务,a,b再事务,没有哪一个结束,只有两个都进入事务后,才能结束期中一个事务,两个事务都是存活的)

1 a  开启事务  将jason的年龄改成 18岁,但是没有提交事务
2 b  开始事务  读取jason的年龄,发现是18岁。

上述的问题,
假设a事务回滚,b事务使用的数据就是错误的,就导致程序数据不正确。

不可重复度(a,b同时开始事务,a,b再事务,没有哪一个结束,只有两个都进入事务后,才能结束期中一个事务,两个事务都是存活的) read committed

1 a  开始事务  将jason的年龄改成18岁,但是提交了
2 b  开启事务  读取jason的年龄就能读取a事务修改后的jason年龄18岁。

# 如果a未提交,b读取jason年龄会卡死

可重读读(a,b同时开始事务,a,b再事务,没有哪一个结束,只有两个都进入事务后,才能结束期中一个事务,两个事务都是存活的) repeated read

1 a  开始事务  将jason的年龄改成18岁,但是提交了
2 b  开启事务  读取jason的年龄不能读取a事务修改后的jason年龄18岁。而是读取的是38岁

幻读(a,b同时开始事务,a,b再事务,没有哪一个结束,只有两个都进入事务后,才能结束期中一个事务,两个事务都是存活的) serializable解决幻读问题

#概念和不可重读有点像,不可重复度是站在修改的基础上,而幻读是站在新增的基础上
1 a  开始事务  将所有的的年龄改成18岁
2 b  开始事务  新增一条数据数据name=tank,age=19,而且提交了。
3 a  重新查, 发现有一条数据 的age=19,这就是所谓的幻读。

如何看msql的隔离级别

select @@global.tx_isolation;    # 默认为 REPEATABLE-READ

如何修改事务的隔离级别

#修改配置文件     可在mysql文件夹中my.ini配置文件中查看
transaction-isolation=Read-Committed
#修改后一定要重启数据库    (删除后回复默认REPEATABLE-READ)

数据库的乐观锁与悲观锁(是建立再事务的基础上)

悲观锁

悲观锁的概念,他觉有人会修改我读的数据。那我就再查的时候,对数据进行锁定。
(悲观锁:假定会发送并发从图,屏蔽一切可能违反数据完整性的操作,理论上别人可以查)

select age from user where id=1 for update;
比如 上面的查出来的 age =18
update age改成age = age+ 1
如果该次查询走了索引,那就是行锁,如果没有走索引就是表锁。

如何释放锁呢?结束事务就释放了锁。    (commit或者rollback)
django中的orm是如果用悲观锁?
user.objects.select_for_update().filter(id=1).first()

mysql使用悲观锁

原生的sql语句:
1 开启事务
2 查询的时候加锁---》select * from user where id =1 for update
3 当结束事务锁就被释放
django中的:
1 开始事务
2 在查询的时候 ----》 User.objects.select_for_update().filter(id =1 ).first()
3 可以对数据进行修改,数据永远不会被比如人修改,只有你自己能动
4 当结束事务锁就被释放

乐观锁

乐观锁的本质不是锁。他是通过代码来实现锁的。他觉的别人不会修改的他的数据。他就读数据不会背别人修改。最后再修改该条数据,再where条件中添加,之前查出来的数据。以保证数据的安全性
select age from user where id=1 ;
比如 上面的查出来的 age =18
20
update age改成age = age+ 1  ====》19

乐观锁:
update age改成age = age+ 1 where age =18 and id =1  ====》19
如果我发现不是18,上面的影响行数是0

#如果是可重复读,上面的乐观锁无效,必须改成read committed    *django2.0以后,用乐观锁不需要修改隔离级别(应该是局部修改)*
a update age改成age = age+ 1  ====》19 提交

b select age from user where id=1; --->18     # 可重复读隔离界别下的情况,乐观锁失效

update age改成age = age+ 1 where age =18 and id =1  ====》19  ---->数据已经被改

mysql使用乐观锁(如果使用乐观锁,mysql隔离级别要变成read committed,在django2.0以后,用乐观锁不需要修改隔离级别)

乐观本质不是锁,是通过代码级别实现数据安全
1 开始事务
2 查询的时候不要做任何操作data= User.objects.filter(id =1 ).first()将这个条数据中的age在原来的基础上加1
3 在修改数据的时候。User.objects.filter(id = 1 ,age = data.age).update(age = data.age+1)从而保证在我查询到我修改的这段时候,没有人动过我的数据。
4 如果3中的更新的影响行数为1,说明数据没有被别人改动,只我动,如果3中的影响行数为0,说明该数据已经被别人修改。这时我们想要改数据,就必须重复执行2-3两不,直到3有影响行数。

另一种事务开启方式

django transaction用法
from django.db import transaction
from django.http import HttpResponse
from django.utils.decorators import method_decorator

# 类中添加装饰器,保证在该类中所有的数据库操作都在一个事物中
@method_decorator(transaction.atomic, name=‘dispatch‘)
class MyView1(object):

    def get(self, request):
        return HttpResponse(‘GET‘)

    def post(self, request):
        return HttpResponse(‘POST‘)

class MyView2(object):

    # 保证在该函数中所有的数据库操作都在一个事物中
    @transaction.atomic
    def post(self, request):

        # 设置事物保存点(可设多个)
        t1 = transaction.savepoint()

        # 如果有异常情况可回滚到指定的保存点
        transaction.savepoint_rollback(t1)

        # 如果没有异常可提交事物
        transaction.savepoint_commit(t1)
        return HttpResponse(‘POST‘)

回滚点可以参考

https://blog.csdn.net/rockpk008/article/details/25437415

原文地址:https://www.cnblogs.com/ludingchao/p/12554513.html

时间: 2024-10-29 04:05:02

事务的隔离级别 另一种事务开启方式的相关文章

spring事务中隔离级别和spring的事务传播机制

Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是一个不可分割的整体,就像我们在化学课里学到的原子,原子是构成物质的最小单位.于是,人们就归纳出事务的第一个特性:原子性(Atomicity).我靠,一点都不神秘嘛. 特别是在数据库领域,事务是一个非常重要的概念,除了原子性以外,它还有一个极其重要的特性,那就是:一致性(Consistency).也就

事务的隔离级别和传播行为

一.事务的隔离级别 1.五种事务的隔离级别 ①读_未提交(read_uncommitted): 会出现脏读.不可重复读.幻读.(隔离级别最低,并发性能高) ②读_已提交(read_committed):会出现不可重复读.幻读.(锁定正在读取的行) ③重复读(repeatable_read):会出现幻读.(锁定所读取的所有行) ④序列化(serializable):保证所有的情况不会发生:(锁表) ⑤默认的隔离级别: 大多数的默认隔离级别是:读已提交(read_commited)如:Sql Ser

数据库事务的隔离级别简单总结

数据库中事务的隔离级别有四种,级别由低到高分别为:Read uncommitted.Read committed. Repeatable read和Serializable 四种.这四个级别可以逐个解决脏读.不可重复读.幻读这几个问题. 如果当前隔离级别为Read uncommitted时,可能出现脏读,即可能读到还未提交的临时写数据. 如果当前隔离级别为Read committed时,能够避免脏读,但可能造成不可重复读,即两个事务同时对同一个数据进行修改时,发生的数据一致性和完整性的破坏.大部

mysql事务以及隔离级别

mysql事务以及隔离级别 1. 简介 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务! 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务. 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行. 事务用来管理 insert,update,delete 语句 2. 事务的基

什么是事务?事务的四个特性以及事务的隔离级别

什么是事务 事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消.可以通俗理解为:就是把多件事情当做一件事情来处理,好比大家同在一条船上,要活一起活,要完一起完 . 事物的四个特性(ACID) ● 原子性(Atomicity):操作这些指令时,要么全部执行成功,要么全部不执行.只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态. eg:拿转账来说,假设用户A和用户B两者的钱加起来一共是20000,那么不管

Spring的4种事务特性,5种隔离级别,7种传播行为

spring事务: 什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种): 原子性 (atomicity):强调事务的不可分割. 一致性 (consistency):事务的执行的前后数据的完整性保持一致. 隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰 持久性(durability) :事务一旦结束,数据就持久到数据库 如果不考虑隔离性引发安全性问题: 脏读 :一个事务读到了另一个事务的未提交的数据 不可重

MYSQL数据库事务4种隔离级别及7种传播行为

事务的特性: 原子性:事务的不可分割,组成事务的各个逻辑单元不可分割. 一致性:事务执行的前后,数据完整性保持一致. 隔离性:事务执行不应该受到其他事务的干扰. 持久性:事务一旦结束,数据就持久化到数据库中. 查看/设置隔离级别 查看:SELECT @@tx_isolation  设置:set tx_isolation='xxx' 事务的隔离级别 如果不考虑隔离性,引发一些安全问题 隔离性:一个事务的执行,不应该受到其他事务的干扰. 脏读:一个事务读到了另一个事务未提交的数据,导致查询结果不一致

事务、事务的四大特性(ACID)、三大并发问题、四种锁、事务的隔离级别

一.什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事务的结果有两种:当事务中的所有步骤全部成功执行完成时,事务提交.如果其中一个步骤失败,将发生回滚操作,撤消之前到事务开始时的所有操作. 二.事务的四个特性 事务具有四个特征:原子性( Atomicity ).一致性( Consistency ).隔离性( Isolation )和持续性( Durabil

深入分析事务的隔离级别

本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接是互不影响的,所以,在多个事务并发操作的过程中,如果控制不好隔离级别,就有可能产生脏读.不可重复读或