编程之事务

1.事务的概念

是逻辑上的一组操作,要么都执行,要么都不执行.
例:在事务数据库中,一个事务可以是一条或者多条SQL语句。
事务通常由高级数据库操纵语言(如SQL等)或编程语言(如C++,Java等)书写的用户程序的执行所引起.

2.事务的特性

原子性(atomicity): 事务是一个不可分割的工作单位.
一致性(consistency): 事务的前后数据保持一致.
隔离性(isolation): 多事务之间数据要相互隔离.
持久性(durability): 事务一旦提交,它对数据的改变就是永久的.

2.1 因事务的隔离性产生的问题:

在多线程并发访问中,多个线程操作了相同的数据,多个事务并发运行,从而引发:
1 脏读: 一个事务读取到了另外一个事务尚未提交的数据.
2 不可重复读: 一个事务在两次读取数据间,另外一个事务进行了修改该数据.
3 幻读:一个事务在两次读取数据间,另外一个事务进行了数据的插入或删除.

2.2 事务的隔离级别:

read uncommitted: 可以读取未提交的数据:隔离级别最低,允许所有问题的发生.
read committed: 可以读取已经提交的数据 : 解决了脏读的问题.---- oracle默认的
repeatable read: 可以重复读取数据: 解决了脏读和不可重复的问题 ----mysql默认的
serializable:串行化:要求事务序列化串行执行.解决了脏读,不可重复读,幻读的问题.------相当于锁表.

2.3 锁

粗粒度分为: 共享锁/读锁 ( S/R ) 以及 排他锁/写锁 ( X/W )
链接详解: mysql锁

2.4 隔离级别与锁的关系

在Read Uncommitted级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突
在Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;
在Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。
SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。

2.5 数据库是如何实现不同隔离级别的

通过 一级封锁协议 二级封锁协议 三级封锁协议
一级封锁:修改数据加x锁直到事务结束才释放。在此协议中,仅仅是读数据是不需要加锁的,所以只能解决丢失修改问题,不能解决脏读和不可重复读。
二级封锁:在一级封锁的基础上,加了一条:T事务在读取数据R之前必须先对其加上S锁,读完释放S锁。可以解决丢失修改和脏读(加了读锁就可以防止在读的期间其他事务进行修改,但是读完之后,事务结束之前,依然可能会其他事务进行修改,导致不可重复读)。
三级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。:解决了丢失修改、脏读和不可重复读的问题。
链接详解:数据库原理 封锁协议
链接详解:详见 第11章 并发控制

3. 编程语言中的事务控制

3.1 jdbc事务原理

    获取链接并设置autocommit(false)
    执行sql语句,并commit
    出错,rollback

3.2 spring的事务控制

spring的事务控制分为声明式事务和编程式事务
编程式事务就是自己调用spring提供的事务api;
声明式事务基于aop思想,通过xml或注解配置来完成.其本质就是在方法前后进行拦截,在方法开始之前进行拦截,在方法结束后根据情况提交或者回滚事务.优点是可以做到事务代码和业务代码完全分离,然后通过配置的方式实现运行时组装.
缺点是只能作用到方法级别,无法像编程式事务那样作用到代码块级别.
总结:Spring中的事务控制主要就是通过这三个API实现的
PlatformTransactionManager 负责事务的管理,他是个接口,其子类负责具体工作
TransactionDefinition 定义了事务的一些相关参数
TransactionStatus 代表事务运行的一个实时状态
可以简单的理解三者的关系:事务管理器通过读取事务定义参数进行事务管理,然后会产生一系列的事务状态。

3.3 spring事务的传播行为:

事务的传播行为:当一个事务方法被另外一个事务方法调用时,应该如何进行事务控制.
spring定义7种传播行为:
REQUIRED(必须有事务,这是默认值)
如果存在一个事务,则加入到当前事务。如果没有事务则开启一个新的事务。
REQUIRES_NEW(必须有新的)
总是开启一个新的事务。如果存在一个事务,则将这个存在的事务挂起,再来一个新的。
SUPPORTS(支持有事务)
如果存在一个事务,则加入到当前事务。如果没有事务则非事务运行。
NOT_SUPPORTED(不支持有事务)
总是非事务地执行,并挂起任何存在的事务。
MANDATORY(强制有事务,自己还不负责创建)
如果存在一个事务,则加入到当前事务。如果没有事务,则抛出异常。
NEVER(强制不要事务,自己还不负责挂起):
总是非事务地执行,如果存在一个活动事务,则抛出异常。
NESTED(嵌套事务)
如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务, 则开启一个新的事务。
内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。
而内层事务操作失败并不会引起外层事务的回滚。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值