Spring事务

一. 事务特性ACID

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

二. 事务管理器

Spring并不直接管理事务,而是提供事务管理器接口,让框架自己(包括JDBC、hibernate、JPA、JTA等)实现具体的事务管理。

2.1 spring提供的事务管理器接口

包括3个接口:获取事务状态、提交、回滚

package org.springframework.transaction;

public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;

    void commit(TransactionStatus var1) throws TransactionException;

    void rollback(TransactionStatus var1) throws TransactionException;
}

2.2 具体实现(以JDBC为例):

DataSourceTransactionManager通过DataSource获取到java.sql.Connection,再调用java.sql.Connection来管理事务

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="具体数据源"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

三. 事务基本属性

上文提到的spring事务管理器接口中,用于获取事务状态的getTransaction方法参数定义了一个事务的基本属性

TransactionStatus getTransaction(TransactionDefinition var1)

事务基本属性包括5类:

  • 传播行为
  • 隔离级别
  • 是否只读
  • 超时时间
  • 回滚规则
public interface TransactionDefinition {

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();

    boolean isReadOnly();

    String getName();
}

3.1 传播行为 PROPAGATION

定义一个事务被另一个事务调用时,两个事务之间的关系,如:被调用事务合并到调用事务中运行,或者独立开启一个新事务运行等。

Spring定义了七种传播行为:

  • require_new(本身执行时是事务,被事务调用时也不合并为同一个事务)
  • require(本身执行时是事务,被事务调用时可合并在同一个事务里)
  • support(本身执行时不是事务,被事务调用时可合并在同一个事务里)
  • not_support(总是非事务地执行,并挂起任何存在的事务)
  • mandatory(本身执行时抛出异常,被事务调用时可合并在同一个事务里)
  • never(总是非事务地执行,如果被其它事务调用则抛出异常)
  • nest(嵌套事务,本身执行时是事务,被事务调用时也不合并为同一个事务,但是外层事务失败时内层事务也要回滚)

3.2 隔离级别

定义了一个事务可能受其他并发事务影响的程度

1.并发事务问题:

  • 脏读(一个事务读取了另一个事务改写但尚未提交的数据时,改写在稍后被回滚了,那么第一个事务获取的数据就是无效的)
  • 不可重复读
  • 幻读(事务T1读取了几行数据,接着另一个并发事务T2插入了一些数据,故在随后的查询中,事务T1就会发现多了一些原本不存在的记录)

不可重复读的重点是同一个数据被修改了,幻读的重点在于有数据新增或者删除。

从结果看, 似乎不可重复读和幻读都表现为两次读取的结果不一致。但如果从控制的角度来看, 两者的区别就比较大:

  • 对于前者, 只需要锁住满足条件的记录
  • 对于后者, 要锁住满足条件及其相近的记录

2.隔离级别

  • defaul(使用数据库默认隔离级别)
  • read_uncommit(允许读取未commit数据,会导致上面3种问题)
  • read_commit(允许读取commit数据,仅可避免脏读)
  • repeatable_read(数据只可被自身事务修改,可避免脏读、不可重复读)
  • Serializable(完全满足ACID,通常是锁表实现)

3.3 是否只读

如果事务只对数据库进行读操作,则数据库可以进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为合适的优化措施。

3.4 超时时间

事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。

3.5 回滚规则

默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)

但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。

四. spring事务实现方式

  • 编程式事务(侵入到业务代码里,但提供了更加详细的事务管理)
  • 声明式事务(基于AOP,不影响业务代码的具体实现)

4.1 编程式事务

  • 使用TransactionTemplate
  • 直接使用PlatformTransactionManager

4.2 声明式事务

  • 每个Bean都有一个代理
  • 所有Bean共享一个代理基类
  • 使用拦截器
  • 使用tx标签配置的拦截器
  • 全注解

4.3 demo(声明式事务,全注解方式)

使用@Transactional注解

    /**
     * 1.propagation 指定事务的传播行为
     * 默认取值为REQUIRED,即使用调用方法的事务
     * 设置为REQUIRES_NEW,即使用自己的事务,调用方法的事务被挂起
     * 2.isolation 指定事务的隔离级别,最常用的取值为READ_COMMITTED
     * 3.Spring 的声明式事务默认对所有运行时异常进行回滚,也可以通过对应的属性进行自行设置
     * 4.readOnly 指定事务是否为只读,若这个事务只读取数据则设置为true,可帮助数据库引擎优化事务
     * 5.timeOut 指定强制回滚之前事务可以占用的时间
     */
    @Transactional(propagation=Propagation.REQUIRES_NEW,
            isolation=Isolation.READ_COMMITTED,
            noRollbackFor={UserAccountException.class},
            readOnly=true, timeout=3)
    @Override
    public void purchase(String username, String isbn) {
        //1.获取书的单价
        int price = bookShopDao.findBookPriceByIsbn(isbn);
        //2.更新书的库存
        bookShopDao.updateBookStock(isbn);
        //3.更新用户余额
        bookShopDao.updateUserAccount(username, price);
    }

测试事务的传播行为

@Transactional
    @Override
    public void checkout(String username, List<String> isbns) {
        for(String isbn : isbns) {
            bookShopService.purchase(username, isbn);
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 很多人喜欢这篇文章,特此同步过来 由浅入深谈论spring事务 前言 这篇其实也要归纳到《常识》系列中,但这重点又...
    码农戏码阅读 4,726评论 2 59
  • Spring 事务属性分析 事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的...
    壹点零阅读 1,301评论 0 2
  • 事务有四个特性:ACID 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作...
    jiangmo阅读 1,229评论 0 7
  • 冬季气温较低气候干燥,各施工项目应该更加注重安全生产和隐患防范,时刻注意以下几个方面的问题: 1 强化现场管理 遇...
    凤凰磐石阅读 262评论 0 0