文档章节

事务

ikate
 ikate
发布于 2017/05/29 14:44
字数 1140
阅读 15
收藏 0

事务

什么是事务?

事务:并发控制的基本单位,它是一个操作序列,这些操作要么全部执行,要么都不执行。

事务的特性:

原子性:事务中包含的操作被看作一个逻辑单元;

一致性:合法的数据可以写入数据库,否则回滚到最初的状态;

隔离性:并行事务修改数据与其他事务修改相互独立;

持久化:事务结束后,处理结果固话。

 

数据并发问题

存款例子:

丢失或覆盖数据更新

用户A 用户B
开启事务 开启事务
查余额1000 查余额1000
取500 取500
   
余500 余500
   
提交事务 提交事务

脏读
A读B事务未提交,丢失更新余额为1000元

用户A 用户B
开启事务 开启事务
  查余额1000
  取500余500
查余额500  
存100 撤销操作查余1000
查余600  
提交事务 提交事务

 

不可重复读

A读B事务已提交,丢失更新余额为1000元

用户A 用户B
开启事务 开启事务
查余额1000 查余额1000
  取500余500
  提交事务
查余额500  
   
提交事务  

 

幻象读

A读B事务已提交新数据

用户A 用户B
开启事务 开启事务
查余额1000 查余额1000
存500 存500
  提交事务
查余额2000  
   
提交事务  

 

数据库阶段事务控制:


1.排他锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。


2.共享锁又称为读锁。若事务T对数据对象A加上S锁,则其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

 

 

jdbc阶段事务控制:

jdbc 3.0之前对事物进行提交和回滚两种方式。

jdbc3.0之后加入节点,设置事务节点。

 

spring声明式事务和编程式事务

1.声明式事务

通过AOP得到各个service的节点,(事务边界设置在service层,既可以增加dao层粒度大小,又有益于二级缓存)在每个节点上加入事务控制TransactionManager

在事务控制中声明各个添加事务的名称(一般用前缀如:add*)

其中的propagation值:

①propagation=“required”   若存在事务,支持当前事务;如没有事物,开启事务;

②propagation=“supports”   若存在事务,支持当前事务;如没有事物,非事务执行;

③propagation=“mandatory”   若存在事务,支持当前事务;如没有事物,抛异常;

④propagation=“required_new”  开启事务;若存在事务,将存在事务挂起;

⑤propagation=“not_supports”   总非事务执行,将任何存在事务挂起;

⑥propagation=“never”   总非事务执行,存在事务抛异常;

⑦propagation=“nested”   若存在事务,运行在嵌套事务中;如没有事物,开启事务;

 

<!-- 事务管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
     <!-- aspect -->
    <aop:config>
        <aop:pointcut id="businessService"
               expression="execution(public * com.ssm.smile.*.serviceimpl..*.*(..))"/>
        <aop:advisor pointcut-ref="businessService" advice-ref="tx-advice"/>
    </aop:config>

    <tx:advice id="tx-advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
           </tx:attributes>
    </tx:advice>

编程式

TransactionTemplate继承了DefaultTransactionDefinition,它是TransactionDefinition的一个实现,TransactionDefinition是Spring事务管理中很重要的一个概念,它是事务配置的入口,可以配置事务的各种属性,如隔离级别、传播属性、超时时间、是否只读,通过实现这个接口,TransactionTemplate具备了配置事务的能力。另外必须为它指定transactionManager,毕竟它只是负责触发事务的开启,并不具备事务管理的能力。

在事务中之行的逻辑封装成TransactionCallback<T>,不带返回值的封装成

TransactionCallbackWithoutResult。

需要执行事务的业务逻辑被封装成action,它所做的也很简单,在action执行前后进行事务的开启和提交(或着rollback)。开启事务时需要transactionManager的getTransaction方法获取TransactionStatus,而这个方法的参数是TransactionDefinition,前面说过TransactionTemplate本身就是TransactionDefinition的实现,所以将this作为参数传递给这个方法就可以。

 

 

 

© 著作权归作者所有

ikate
粉丝 0
博文 4
码字总数 1564
作品 0
洛阳
私信 提问

暂无文章

JAVA 编写redisUtils工具类,防止高并发获取缓存出现并发问题

import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.BoundHashOperations;import org.springframework.data.redis.core.BoundValueOperations;import org.......

huangkejie
28分钟前
4
0
JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
46分钟前
90
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
55分钟前
4
0
正则表达式基础(一)

1.转义 转义的作用: 当某个字符在表达式中具有特殊含义,例如字符串引号中出现了引号,为了可以使用这些字符本身,而不是使用其在表达式中的特殊含义,则需要通过转义符“\”来构建该字符转...

清自以敬
58分钟前
4
0
idea中@Data标签getset不起作用

背景:换电脑以后在idea中有@data注解都不生效 解决办法:idea装个插件 https://blog.csdn.net/seapeak007/article/details/72911529...

栾小糖
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部