spring事物与传播行为
一、事物的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。
作用:事物就是保证数据的一致性
事物的特性:事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性 (isolation)和持久性(durability)的缩写。
原子性:原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性:一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。(如AB用户无论如何转账,总量不变,保持一致。)
隔离性:隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性:持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
二、程序中事务控制
一个业务的成功:调用的service是执行成功的,意味着service中调用的所有的dao是执行成功的。事务应该在Service层统一控制。
2.1 编程式事物
自己手动控制事务,就叫做编程式事务控制
Jdbc代码: Conn.setAutoCommite(false); // 设置手动控制事务
Hibernate代码: Session.beginTransaction(); // 开启一个事务
细粒度的事务控制:可以对指定的方法、指定的方法的某几行添加事务控制。(比较灵活,但开发起来比较繁琐:每次都要开启、提交、回滚.)
2.2 声明式事物
Spring提供了对事务的管理, 这个就叫声明式事务管理。
Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可;不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
Spring声明式事务管理,核心实现就是基于Aop。
粗粒度的事务控制:只能给整个方法应用事务,不可以对方法的某几行应用事务。(因为aop拦截的是方法。)
Spring声明式事务管理器类:
dbc技术:DataSourceTransactionManager
Hibernate技术:HibernateTransactionManager
案例:
dao层
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
publicvoid add(String name, Integer age) {
String sql = "INSERT INTO users(NAME, age) VALUES(?,?);";
intupdate = jdbcTemplate.update(sql, name, age);
System.out.println("updateResult:" + update);
}
}
service层
@Autowired
private TransactionManager transactionManager; public void add() {
TransactionStatus status = null;
try {
status = transactionManager.begin();
String username = "zs" + System.currentTimeMillis();
String username2 = "ls" + System.currentTimeMillis();
String pwd = "123";
userDao.add(username, pwd);
// int i = 1/0;
userDao.add(username2, pwd);
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
e.printStackTrace();
}
}
测试
public class UserTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
userService.add();
}
}
手动事物管理类
@Component
public class TransactionUtils {
// 事物管理器
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
public TransactionStatus begin() {
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionDefinition());
returntransaction;
}
public void commit(TransactionStatus transaction) {
dataSourceTransactionManager.commit(transaction);
}
public void rollback(TransactionStatus transaction) {
dataSourceTransactionManager.rollback(transaction);
}
}
spring.xml(spring管理配置)
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 开启注解 -->
<context:component-scanbase-package="com.stu"></context:component-scan>
<!-- 1. 数据源对象: C3P0连接池 -->
<beanid="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<propertyname="driverClass" value="com.mysql.jdbc.Driver"></property>
<propertyname="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<propertyname="user" value="root"></property>
<propertyname="password" value=""></property>
</bean> <!-- 2. JdbcTemplate工具类实例 -->
<beanid="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<propertyname="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事物 -->
<beanid="DataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource" ref="dataSource"></property>
</bean>
</beans>
注解版事物
<!--开启事物注解-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
service添加注解
@Transactional
public void add(){
String username = "zs"+System.currentTimeMillis();
String username2 = "ls"+System.currentTimeMillis();
String pwd = "123";
// try {
userDao.add(username,pwd);
// int i = 1/0; userDao.add(username2,pwd);
// }catch (Exception e){
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// }
System.out.println("********************************方法执行完成。。。。。");
}
注意:
1)事物是程序运行如果没有错误,会自动提交事物,如果程序运行发生异常,则会自动回滚。如果使用了try捕获异常时.一定要在catch里面手动回滚。
事物手动回滚代码:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
2)数据库表中的主键如果是自增的,调用插入方法,即使被回滚了。该自增的ID也是已经被使用了
3)spring报错org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
原因:对应要注入的实现类没有 加注解,如component,dao层 @Repository 如service层 @Service
解决:在相应的实现类加上注解即可
三、spring的传播行为
Spring中事务的定义:Propagation(key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。)
- PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。(默认)
- PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
@Transactional(
readOnly = false, // 读写事务
timeout = -1, // 事务的超时时间不限制
noRollbackFor = ArithmeticException.class, // 遇到数学异常不回滚
isolation = Isolation.DEFAULT, // 事务的隔离级别,数据库的默认
propagation = Propagation.REQUIRED // 事务的传播行为
)举例:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void add(){
String username = "zs"+System.currentTimeMillis();
String pwd = "123";
//无论该方法是否能完成走完,日志一定要存入
logService.addLog();
userDao.add(username,pwd);
// int i = 1/0;
System.out.println("********************************方法执行完成。。。。。");
} class LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addLog(){ }
}
spring事物与传播行为的更多相关文章
- spring事物的传播行为
1.spring事物的传播行为,主要是用来解决业务层拥有事物的方法,相互调用的问题. 2.声明事物, 在代码执行前,开启事务.代码执行完,提交事务 3.spring并没有提供事务具体的处理,而只是调用 ...
- spring事物的传播行为及隔离
关于@Transactional注解: 添加事务注解1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时如何使用事务, 默认取值为 REQUIRED, 即使 ...
- Spring事物的传播
spring的事物对于同一个类内部调用是不会生效的. 比如一个ServiceA,里面有个方法x()和y().其中x没有配置事物,而y配置的有实物.如果是一个没有事物的ServiceB调用了Servic ...
- 【连接】Spring事物的传播行为
http://blog.csdn.net/it_wangxiangpan/article/details/24180085 PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务, ...
- Spring 事物传播特性
Spring 事物传播特性 这是Spring官方的定义 一共有7种 摘自源码省略了一部分 public interface TransactionDefinition { int PROPAGATIO ...
- Spring 事物隔离级别,事物传播行为
Spring 框架中对于事物的管理,主要定义了一下四种属性: 事物的隔离(Isolation)级别 事物的传播行为(Propagation Behavior) 事物的超时时间(TImeout) 是否为 ...
- Spring事物传播行为
Spring事物传播行为 Spring中事务的定义: Propagation(key属性确定代理应该给哪个方法增加事务行为.这样的属性最重要的部份是传播行为.)有以下选项可供使用: PROPAGATI ...
- spring事物传播机制与隔离级别
转载自:http://www.blogjava.net/freeman1984/archive/2010/04/28/319595.html7个传播行为,4个隔离级别, Spring事务的传播行为和隔 ...
- 关于spring 事物传播性的研究
spring的一大特色就是数据库事务管理方便,我们在代码中编写代码时,看不到事务的使用,关键是spring 使用了AOP进行事务拦截. 这篇文章主要介绍spring的事务传播性. 1.为什么要 ...
随机推荐
- SpringBoot系列——Spring-Data-JPA(究极进化版) 自动生成单表基础增、删、改、查接口
前言 我们在之前的实现了springboot与data-jpa的增.删.改.查简单使用(请戳:SpringBoot系列——Spring-Data-JPA),并实现了升级版(请戳:SpringBoot系 ...
- Css-移动端适配总结
前言 工作以后,大部分的业务工作都是基于移动端H5的,开发过程中学习了很多东西,遇到过许多问题,诸如rem\em\css px\device px等,本文纯属个人的归纳总结,如有问题,请指出亲喷~ P ...
- 学代码第十七天,JAVA继承
JANA面向对象的三大特性:封装,继承,多态. 今天学了继承,继承,通俗点说就是子类可以用父类的代码,或重写父类的方法.构造方法.属性 例如我这里要调用父类的方法: 下边有两个测试类,自己分别试一下, ...
- 小程序中使用ECharts 异步加载数据
官网例子都是同步的,怎么引入及同步demo请移步官网 <view class="container"> <ec-canvas id="mychart-d ...
- Nginx日志常用统计分析命令
IP相关统计 统计IP访问量(独立ip访问数量) awk '{print $1}' access.log | sort -n | uniq | wc -l 查看某一时间段的IP访问量(4-5点) gr ...
- HBase单机模式部署
1.上传&解压 2.设置环境变量 3.启用&检验 4.编辑hbase-env.sh 5.编辑hbase-site.xml 6.启动hbase 7.验证 8.启动hbase shell
- java 位运算符 以及加法 交换两个变量值
先给出十转二的除法 2 60 30 0 15 0 7 1 3 1 1 1 0 1 60转二 111100 再介绍位运算符 a=60 b=13 A = 0011 1100 B ...
- HTML基础-------最初概念以及相关语法
HTML概念以及相关语法 HTML HTML是一种类似于(c,java,c++)之类的语言,他是用来描述网页的一种语言.通过各种标签所代表的语义来构建出一个网页,再通过浏览器的渲染功能来实现该网页的各 ...
- [已解决]ValueError: row index was 65536, not allowed by .xls format
报错: ValueError: row index was 65536, not allowed by .xls format 解决方案: xlrd和xlwt处理的是xls文件,单个sheet最大行数 ...
- CSAPP:第十章 系统级I/O
CSAPP:第十章 系统级I/O 10.1 unix I/O10.2 文件10.3 读取文件元数据10.4 读取目录内容10.5 共享文件10.6 我们该使用哪些I/O函数? 10.1 unix I/ ...