什么是事务

举例:A给B转500,两个动作,A的账户少500,B的账户多500

事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用

一、注解添加事务管理方法:

1、配置文件添加事务管理器并启用

<!-- 1. 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 2. 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

2、在需要事务管理的方法上添加@Transactional注解

@Transactional

买一本书的代码

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService { @Autowired
private BookShopDao bookShopDao; @Transactional
@Override
public void purchase(String username, String isbn) { //1. 获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn); //2. 更新书的库存
bookShopDao.updateBookStock(isbn); //3. 更新用户余额
bookShopDao.updateUserAccount(username, price);
} }

二、事务的属性

1、事务的传播

举例:去饭店吃饭,有一桌朋友已经开了一桌,是新开一桌还是一起吃

事务的七种传播行为:

事务的默认传播行为是REQUIRED

在一的基础上添加一个买多本书的方法,并添加@Transactional注解,默认在抛出异常的情况下一本都不会成功,会回滚到最开始的时候。

买多本书的代码

@Service("cashier")
public class CashierImpl implements Cashier { @Autowired
private BookShopService bookShopService; @Transactional
@Override
public void checkout(String username, List<String> isbns) {
for(String isbn: isbns){
bookShopService.purchase(username, isbn);
}
} }

@Transactional(propagation=Propagation.REQUIRES)为默认的事务传播行为,在一个事务调用其他事务的时候不会新开事务,只要有事务就会用,也就是为什么在买第二本书时余额不足会导致整个买多本书的事务回滚,因为买单本书时用的就是买多本书的事务。

@Transactional(propagation=Propagation.REQUIRES_NEW)在一个事务调用其他事务的时候,其他事务有自己的事务就会用自己的事务,这样买多本书的时候,用的都是买单本书的事务,当抛出异常的时候,回滚的是买单本书的事务,如果前面有买单本书成功不会被回滚。

(买多本书的事务去调用买单本书的事务,可以通过@Transactional的propagation属性修改事务的传播方式)

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService { @Autowired
private BookShopDao bookShopDao; //添加事务注解
//1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时
//如何使用事务, 默认取值为 REQUIRED, 即使用调用方法的事务
//REQUIRES_NEW: 使用自己的事务, 调用的事务方法的事务被挂起.
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public void purchase(String username, String isbn) {
//1. 获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn); //2. 更新数的库存
bookShopDao.updateBookStock(isbn); //3. 更新用户余额
bookShopDao.updateUserAccount(username, price);
} }

举例:

REQUIRED一起吃

REQUIRED_NEW自己吃

图解:

REQUIRED的传播行为

REQUIRED_NEW的传播行为

三、事务其他属性(隔离级别&回滚&只读&过期)

1、隔离级别

使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED

2、设置事务回滚属性

默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的属性进行设置. 通常情况下去默认值即可.

3、设置事务超时属性

使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true

4、设置事务只读属性

使用 timeout 指定强制回滚之前事务可以占用的时间.

//    @Transactional(propagation=Propagation.REQUIRES_NEW,
// isolation=Isolation.READ_COMMITTED,
// noRollbackFor={UserAccountException.class})
@Transactional(propagation=Propagation.REQUIRES_NEW,
isolation=Isolation.READ_COMMITTED,
readOnly=false,
timeout=3)
@Override
public void purchase(String username, String isbn) { try {
Thread.sleep(5000);
} catch (InterruptedException e) {} //1. 获取书的单价
int price = bookShopDao.findBookPriceByIsbn(isbn); //2. 更新数的库存
bookShopDao.updateBookStock(isbn); //3. 更新用户余额
bookShopDao.updateUserAccount(username, price);

四、基于XML文件的方式配置事务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.spring"></context:component-scan> <!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/> <!-- 配置 C3P0 数据源 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean> <!-- 配置 Spirng 的 JdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置 bean -->
<bean id="bookShopDao" class="com.spring.tx.xml.BookShopDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <bean id="bookShopService" class="com.spring.tx.xml.service.impl.BookShopServiceImpl">
<property name="bookShopDao" ref="bookShopDao"></property>
</bean> <bean id="cashier" class="com.spring.tx.xml.service.impl.CashierImpl">
<property name="bookShopService" ref="bookShopService"></property>
</bean> <!-- 1. 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 2. 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 根据方法名指定事务的属性 -->
<tx:method name="purchase" propagation="REQUIRES_NEW"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.spring.tx.xml.service.*.*(..))"
id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config> </beans>

Spring框架学习笔记(10)——Spring中的事务管理的更多相关文章

  1. Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息

    </pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...

  2. Spring框架学习笔记(5)——Spring Boot创建与使用

    Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...

  3. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  4. Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建

    之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...

  5. Spring框架学习笔记(1)

    Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...

  6. Spring MVC 学习笔记9 —— 实现简单的用户管理(4)用户登录显示局部异常信息

    Spring MVC 学习笔记9 -- 实现简单的用户管理(4.2)用户登录--显示局部异常信息 第二部分:显示局部异常信息,而不是500错误页 1. 写一个方法,把UserException传进来. ...

  7. Spring MVC 学习笔记8 —— 实现简单的用户管理(4)用户登录

    Spring MVC 学习笔记8 -- 实现简单的用户管理(4)用户登录 增删改查,login 1. login.jsp,写在外面,及跟WEB-INF同一级目录,如:ls Webcontent; &g ...

  8. Spring框架学习(10)Spring中如何使用事务?

    内容源自:Spring中如何使用事务? 一.为什么要使用事务? 如果我们一个业务逻辑只执行一次sql,是不需要使用事务的.但如果要执行多条sql语句才能完成一个业务逻辑的话,这个时候就要使用事务了. ...

  9. 手写Spring框架学习笔记

    以下是咕泡公开课的学习笔记 一.创建工程springdemo 二.在pom中配置servlet <dependency> <groupId>javax.servlet</ ...

随机推荐

  1. Java 硬件同步机制 Swap 指令模拟 + 记录型信号量模拟

    学校实验存档//.. 以经典的生产者消费者问题作为背景. 进程同步方式接口: package method; /** * P表示通过,V表示释放 */ public interface Method ...

  2. asp.net MVC分页

    .Net MVC  分页代码,分页的关键就是在于这几个参数pageIndex ,recordCount,pageSize ,下面是张林的网站做的一个简单的分页代码 效果如图 public class ...

  3. Create 命令详解

    mkdir:创建一个目录 /mkdir a b c :创建同级目录 /mkdir -p aa/bb/cc: 递归创建目录touch:修改文件时间戳,或者新建一个不存在的文件 /-a 更改存取时间 /m ...

  4. glibc-commons 依赖解析 版本错误,xxx is duplicate yyy

    glibc-commons 安装了两个版本,导致依赖glibc-commons的很多软件包 被安装了两个版本: 解决办法就是 先清除这些重复的已安装的软件,然后执行 yum update 将 glib ...

  5. php+中文分词scws+sphinx+mysql打造千万级数据全文搜索

    转载自:http://blog.csdn.net/nuli888/article/details/51892776 Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎.意图 ...

  6. parse_str 与 http_build_query的使用

    1 http_build_query() 使用 生成 URL-encode 之后的请求字符串 [建议在使用前,使用array_filter($query) 进行处理] 例子 1. http_build ...

  7. c# 去除字符串中重复字符

    String.Join 和 Distinct 方法 https://www.cnblogs.com/louby/p/6224960.html 1.在写程序中经常操作字符串,需要去重,以前我的用方式利用 ...

  8. MySQL 配置文件my.cnf

    转载: MySQL配置文件my.cnf 详解:#BEGIN CONFIG INFO#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大#TYPE: SYSTEM ...

  9. Use Zabbix Monitor Find ‘DBCC CheckDB’ Problem

    下面是修改前后的对比截图: 如下图: 下图是确定问题并修改后对比图,左边圈是修改前,右边圈是修改后对比截图:当看到周期性的性能指数,一般是计划性任务引起:通过DMV视图,找到引起等待的原因检查数据库完 ...

  10. SpringMVC 支持使用Servlet原生API作为目标方法的参数

    具体支持一下类型: * HttpServletRequest * HttpServletResponse * HttpSession * java.security.Pricipal * Locale ...