2019独角兽企业重金招聘Python工程师标准>>>

一、 Spring事务概念:

事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。

在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。

事务有四个特性:ACID

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。

  • 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。

  • 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。

  • 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

举个简单的例子:例如陈多多给陈多糖转钱,但是在转钱的过程中出现了问题,银行系统出现了问题,那么陈多多的钱给陈多糖转过去了,但是陈多糖却没有收到钱?这个就很尴尬

那么怎么避免?出现这个问题啦?这个时候就要用到我们spring中的事务管理

二、用xml的方式实现事务管理

第一步、导jar包

    <dependencies><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- spring start --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-instrument</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-oxm</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>LATEST</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>LATEST</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>LATEST</version></dependency><!-- spring end --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.15</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.0</version><scope>provided</scope></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.0</version></dependency><!-- https://mvnrepository.com/artifact/aspectj/aspectjrt --><dependency><groupId>aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.5.4</version></dependency><!-- https://mvnrepository.com/artifact/aspectj/aspectjweaver --><dependency><groupId>aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.5.4</version></dependency></dependencies><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

第二步、创建Mapper接口和实体类

package com.bdqn.zmj.dao;import com.bdqn.zmj.entity.user;import java.util.List;public interface UserMapper {List<user> GetList();//转出void jian();//转入void add();
}
package com.bdqn.zmj.entity;public class user {int uid;String uname;int money;//注意这里对应的是映射文件里的UserId,而不是这类里的uidpublic int getUserId() {return uid;}public void setUserId(int uid) {this.uid = uid;}public String getUserName() {return uname;}public void setUserName(String uname) {this.uname = uname;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}
}

第三步、创建mybatis映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bdqn.zmj.dao.UserMapper"><resultMap id="userMap" type="user"><id property="userId" column="uid" /><result property="userName" column="uname"/><result property="money" column="money" /></resultMap><select id="GetList" resultMap="userMap">select * from t_user</select><update id="jian">update t_user set money = money-500 where uid =1</update><update id="add">update t_user set money = money +500 where uid =2</update>
</mapper>

第四步、Service层代码

package com.bdqn.zmj.service;import com.bdqn.zmj.dao.UserMapper;
import com.bdqn.zmj.entity.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
/*
* 事务一般都加在service层,因为service调用dao
*   当servoce调用多个dao方法的时候事务如下处理
*   加载controller层:当controller调用多个service方法发的时候事务如何处理
*
* */
@Service
public class UserService{@AutowiredUserMapper dao;public List<user> GetList(){return dao.GetList();}@Transactionalpublic void transfer() {dao.jian();int i = 10/0;dao.add();}
}

第五步、ApplicationContext配置文件、mybatis映射文件、Log4J配置文件、数据库配置文件

<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.bdqn.zmj"/><!--注入配置文件--><context:property-placeholder location="classpath:db.properties"/><!--两个框架整合:几乎所有的配置都交给了spring,因为spring专门做整合--><!--1.数据源--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${driver}"/><property name="jdbcUrl" value="${url}"/><property name="user" value="${user}"/><property name="password" value="${password}"/><!--其他数据库连接池配置省略,比如:连接个数,最大连接数。。。。--></bean><!--配置sqlSessionFactiorBean--><bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="mapperLocations" value="com/bdqn/zmj/mapper/*.xml"></property><property name="dataSource" ref="dataSource"></property></bean><!--配置接口扫描--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.bdqn.zmj.dao"/><property name="sqlSessionFactoryBeanName" value="sessionFactoryBean"/></bean><!--配置事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>配置事务传播行为,就是 有事务的方法调用 没有事务的方法的时候,事务应该如何传递<tx:advice id="txadvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="transfer" propagation="REQUIRED"/></tx:attributes></tx:advice><!--配置切面--><aop:config><aop:pointcut id="pointcut" expression="execution(* com.bdqn.zmj..*.*(..))"/><aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/></aop:config>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--通过这个配置文件,完成mybatis与数据库的连接  -->
<configuration><settings><setting name="logImpl" value="LOG4J"/></settings><!-- 设置类的别名 --><typeAliases><!-- <typeAlias alias="User" type="com.wu.pojo.User"/> --><!-- 根据包取别名,把包下面的所有类都按类名来取别名 --><!-- 这用可以简化代码量 --><package name="com.bdqn.zmj.entity"/></typeAliases></configuration>
log4j.rootLogger=info,CONSOLE
#############################################################
# Console Appender
#############################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=info
##log4j.appender.CONSOLE.DatePattern=yyyy-MM-dd
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= %d{yyyy-M-d HH:mm:ss}%x[%5p] %m%n
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/fresh?serverTimezone=UTC
user=root
password=root

第六步、编写测试类

package com.bdqn.zmj.test;import com.bdqn.zmj.entity.user;
import com.bdqn.zmj.service.UserService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;import java.util.List;public class Testone {ApplicationContext context = null;@Beforepublic void load(){context = new ClassPathXmlApplicationContext("applicationContext.xml");}@Test//事务,下面的方法只有全执行和全不执行两种状态public void test2(){UserService service = context.getBean("userService", UserService.class);service.transfer();}
}

数据库中的数据没有变化,操作失败,数据回滚回去了!!!

二、用注解的方式实现事务管理

只需要改变两个地方即可

第一、service层,方法上加上 @Transactional

package com.bdqn.zmj.service;import com.bdqn.zmj.dao.UserMapper;
import com.bdqn.zmj.entity.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
/*
* 事务一般都加在service层,因为service调用dao
*   当servoce调用多个dao方法的时候事务如下处理
*   加载controller层:当controller调用多个service方法发的时候事务如何处理
*
* */
@Service
public class UserService{@AutowiredUserMapper dao;public List<user> GetList(){return dao.GetList();}@Transactionalpublic void transfer() {dao.jian();int i = 10/0;dao.add();}
}

第二步、ApplicationContext.xml中,只留下配置事务管理器、然后加上扫描事务的<tx:annotation-driven />

<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.bdqn.zmj"/><!--注入配置文件--><context:property-placeholder location="classpath:db.properties"/><!--两个框架整合:几乎所有的配置都交给了spring,因为spring专门做整合--><!--1.数据源--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${driver}"/><property name="jdbcUrl" value="${url}"/><property name="user" value="${user}"/><property name="password" value="${password}"/><!--其他数据库连接池配置省略,比如:连接个数,最大连接数。。。。--></bean><!--配置sqlSessionFactiorBean--><bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="configLocation" value="classpath:mybatis-config.xml"></property><property name="mapperLocations" value="com/bdqn/zmj/mapper/*.xml"></property><property name="dataSource" ref="dataSource"></property></bean><!--配置接口扫描--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.bdqn.zmj.dao"/><property name="sqlSessionFactoryBeanName" value="sessionFactoryBean"/></bean><!--配置事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!--配置事务传播行为,就是 有事务的方法调用 没有事务的方法的时候,事务应该如何传递--><!--<tx:advice id="txadvice" transaction-manager="transactionManager">--><!--<tx:attributes>--><!--<tx:method name="transfer" propagation="REQUIRED"/>--><!--</tx:attributes>--><!--</tx:advice>--><!--&lt;!&ndash;配置切面&ndash;&gt;--><!--<aop:config>--><!--<aop:pointcut id="pointcut" expression="execution(* com.bdqn.zmj..*.*(..))"/>--><!--<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/>--><!--</aop:config>--><tx:annotation-driven />
</beans>

这两种方式都可以实现事务配置、但是我们不配置细节的话,用的都是注解的方式、xml方式用于比较细致的配置,比如什么银行转账什么的

转载于:https://my.oschina.net/u/4115727/blog/3054097

Spring系列教程八: Spring实现事务的两种方式相关推荐

  1. 爆破专栏丨Spring系列教程解决Spring Security环境中的跨域问题

    上一章节中,一一哥 给各位讲解了同源策略和跨域问题,以及跨域问题的解决方案,在本篇文章中,我会带大家进行代码实现,看看在Spring Security环境中如何解决跨域问题. 一. 启用Spring ...

  2. 对spring boot yml配置文件敏感信息加密处理的两种方式

    目录 方式一:手动配置加密处理(手动配置分三种情况) 方式二:spring boot整合Jasypt实现yml配置文件敏感信息加密 yml配置文件敏感信息无非就是数据库密码,redis密码,以及整合的 ...

  3. spring依赖注入简介以及依赖注入的两种方式

    1.spring依赖注入简介 依赖注入:Set注入1.依赖:bean对象创建依赖于容器!2.注入:bean对象中的所有属性,由容器来注入! 2.依赖注入的两种方式   实体类: package com ...

  4. 简单介绍MySQL开启事务的两种方式

    本篇文章给大家分享MySQL 是如何开启一个事务的,原文通过两种方式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧 方式 1 START TRANSACTION 或 ...

  5. springboot转发http请求_Spring Boot2 系列教程(八)Spring Boot 中配置 Https

    https 现在已经越来越普及了,特别是做一些小程序或者公众号开发的时候,https 基本上都是刚需了. 不过一个 https 证书还是挺费钱的,个人开发者可以在各个云服务提供商那里申请一个免费的证书 ...

  6. Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:

    ① JDK动态代理只提供接口的代理,不支持类的代理,要求被代理类实现接口.JDK动态代理的核心是InvocationHandler接口和Proxy类,在获取代理对象时,使用Proxy类来动态创建目标类 ...

  7. freemarker ftl模板_Spring Boot2 系列教程(十)Spring Boot 整合 Freemarker

    今天来聊聊 Spring Boot 整合 Freemarker. Freemarker 简介 这是一个相当老牌的开源的免费的模版引擎.通过 Freemarker 模版,我们可以将数据渲染成 HTML ...

  8. Spring中进行事务管理的两种方式

    1.Spring中事务管理的API 事务是指逻辑上要么全部成功.要么全部失败的一组操作.例如用户A给用户B转账,则用户A账户余额减少.用户B账户增加这两个操作就是一组事务,必须全部成功或失败撤回操作, ...

  9. spring支持事务管理的两种方式

    转载:https://blog.csdn.net/bao19901210/article/details/41724355 事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的一 ...

最新文章

  1. IntelliTest(5) - The IntelliTest Reference Manual[译]
  2. [转]机器视觉开源代码集合
  3. javascript mobile web
  4. TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片
  5. VTK:可视化之BlobbyLogo
  6. php三维数组转换二维数组,php 三维数组转二维数组(多维数组变合拼二维数组)(foreach循环 数组叠加)...
  7. 基础课教材推荐-数字设计、体系结构
  8. 普通摄像头的数据输出格式YUV与mjpeg之间联系、DCT离散余弦变换去噪跟压缩(待补充)
  9. js html实体编码转换,字符串js编码转换成实体html编码的方法(防范XSS攻击)
  10. 网上十大经典黑客软件大曝光(转)
  11. ideaIU-2020.1.3的安装
  12. python计算目标文件夹中各文件的GC含量
  13. C++ primer(第五版)简单读书笔记
  14. 什么是集群和集群的分类
  15. 哪个服务器便宜又稳定,便宜又稳定的云服务器
  16. 淀粉肽β-Amyloid (1-9)、Aβ1-9、147529-30-4
  17. 近视?老花眼?恢复视力,就用这一招!
  18. c++初级(本人scdn)
  19. php代码应该这样写
  20. Scratch学习笔记导图

热门文章

  1. linux机器设置密码,Linux系统设置复杂安全的密码的办法
  2. php 库存自动减少,ECSHOP付款后自动减少库存功能
  3. hook什么意思_这是什么骚代码!
  4. [Swift]LeetCode732. 我的日程安排表 III | My Calendar III
  5. Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表
  6. 《潜意识:控制你行为的秘密》摘录
  7. Redmine环境搭建
  8. AutoLayout自动布局,NSLayoutConstraint 视图约束使用
  9. 关于今天写Flex视频循环播放所出现的sdk问题
  10. 发票抬头是什么意思?