spring31-1: 事务-传播行为
传播行为:在两个事务之间如何共享事务。
PROPAGATION_REQUIRED
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将创建一个新的事务。
PROPAGATION_SUPPORTS
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将以非事务执行。(你有,我也有; 你没有,我也就没有)
PROPAGATION_MANDATORY
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将抛异常。
PROPAGATION_REQUIRES_NEW
如果A有事务, 将A的事务挂起。 B创建一个新的事务。
如果A没有事务,B将创建一个新的事务。
PROPAGATION_NOT_SUPPORTED
如果A有事务, 将A的事务挂起。B将以非事务执行。
如果A没有事务,B将以非事务执行。
PROPAGATION_NEVER
如果A有事务,B将抛异常。
如果A没有事务,B将以非事务执行。
PROPAGATION_NESTED
A和B底层采用保存点机制,形成嵌套事务。
手动管理事物
spring底层使用TransactionTemplate事物模板进行操作。
操作: 1. service需要获得TransactionTemplate 2. spring配置模板,并注入给service 3. 模板需要注入事务管理器 4. 配置事务管理器, DataSourceTransactionManager
Dao类
package com.atchina.d_spring_tx2.dao;public interface AccountDao {// 汇款public void in(String inner, Double money);// 收款public void out(String outter, Double money);
}package com.atchina.d_spring_tx2.dao.impl;import org.springframework.jdbc.core.support.JdbcDaoSupport;import com.atchina.d_spring_tx.dao.AccountDao;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{@Overridepublic void in(String inner, Double money) {String sql = "update bankaccount a set money = money + ? where username = ? ";this.getJdbcTemplate().update(sql, money, inner);}@Overridepublic void out(String outter, Double money) {String sql = "update bankaccount a set money = money - ? where username = ? ";Object[] objs = {money, outter};this.getJdbcTemplate().update(sql, objs);}
}
service类
// 接口
package com.atchina.d_spring_tx2.service;public interface AccountService {public void transfer(String outter, String inner, Double money);
}// 实现类
package com.atchina.d_spring_tx2.service.impl;import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;import com.atchina.d_spring_tx.dao.AccountDao;
import com.atchina.d_spring_tx.service.AccountService;public class AccountServiceImpl implements AccountService{private AccountDao accountDao;private TransactionTemplate transactionTemplate;//spring注入模板public void setTransactionTemplate(TransactionTemplate transactionTemplate) {this.transactionTemplate = transactionTemplate;}public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(final String outter, final String inner, final Double money) {transactionTemplate.execute( new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {accountDao.out(outter, money);int a = 5/0;accountDao.in(inner, money);}});}
}
spring配置文件
<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx2.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx2.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property><property name="transactionTemplate" ref="transactionTemplate"></property></bean><!-- 创建模板 --><bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="txManager"></property></bean> <!-- 配置事务管理器, 管理器需要事务,事务从Connection获得,连接从DataSource获得 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>
</beans>
测试类:
package com.atchina.d_spring_tx2;import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.atchina.d_spring_tx.service.AccountService;public class TestTx {@Testpublic void test(){String xmlPath = "com/atchina/d_spring_tx2/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);AccountService accountService = (AccountService)ac.getBean("accountService");accountService.transfer("tom", "jerry", 500.0);}
}
工厂bean生成代理:半自动
配置文件
<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx3.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx3.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- service代理对象1.proxyInterfaces 接口,2.target 目标类3.transactionManager 事务管理器4.transactionAttributes: 事务属性prop.key: 确定哪些方法使用当前事务配置prop.text: 用于配置事务详情格式: PROPAGATION,ISOLATION,readOnly,-Exception,+Exception传播行为 隔离级别 是否只读 有异常回滚 有异常提交例如: <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认传播行为 ,隔离级别 <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.ArithmeticException</prop>--><bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="proxyInterfaces" value="com.atchina.d_spring_tx3.service.AccountService"></property><property name="target" ref="accountService"></property><property name="transactionManager" ref="dataSourceTransactionManager"></property><property name="transactionAttributes"><props><prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop></props></property></bean>
</beans>
测试类:
public class TestTx {@Testpublic void test(){String xmlPath = "com/atchina/d_spring_tx3/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);AccountService accountService = (AccountService)ac.getBean("proxyAccountService");accountService.transfer("tom", "jerry", 500.0);}
}
AOP配置,基于xml
在spring xml配置aop自动生成代理,进行事务的管理
1.配置管理器 2. 配置事务详情 3.配置aop
<?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:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx4.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx4.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 事务详情(事务通知) 在aop筛选基础上,对筛选出来的方法进行管理<tx:attributes> 用于配置事务详情<tx:method name=""/>详情具体配置propagation 传播行为isolation 隔离级别--><tx:advice id="advice" transaction-manager="transactionManager"><tx:attributes><tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/></tx:attributes></tx:advice><!-- aop编程 --><aop:config><aop:advisor advice-ref="advice" pointcut="execution(* com.atchina.d_spring_tx4.service..*.*(..))"/></aop:config>
</beans>
AOP配置,基于注解
1. 配置事务管理器,并将事务管理器交给spring
2. 在目标类或目标方法添加注解即可 @Transactional
配置文件
<?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:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx5.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx5.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 将事物管理器交给spring --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
service类 加上@Transactional注解
package com.atchina.d_spring_tx5.service.impl;import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.atchina.d_spring_tx5.dao.AccountDao;
import com.atchina.d_spring_tx5.service.AccountService;@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,noRollbackForClassName={"java.lang.ArithmeticException"})
public class AccountServiceImpl implements AccountService{private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(String outter, String inner, Double money) {this.accountDao.out(outter, money);int a = 5/0;this.accountDao.in(inner, money);}
}
与junit整合
package com.atchina.d_spring_tx_test;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.atchina.d_spring_tx_test.service.AccountService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/atchina/d_spring_tx_test/applicationContext.xml")
public class TestTx {@Autowired // 与junit整合,不需要在spring.xml配置扫描private AccountService accountService;@Testpublic void test(){
// String xmlPath = "com/atchina/d_spring_tx_test/applicationContext.xml";
// ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);
//
// AccountService accountService = (AccountService)ac.getBean("accountService");accountService.transfer("tom", "jerry", 500.0);}
}
spring31-1: 事务-传播行为相关推荐
- spring上下文是什么意思_Java程序员只会CRUD连Spring事务传播机制都不懂?
AQS到底有什么用?难道就真的只是为了面试吗? 当然不是说AQS没用,如果你不是做基础架构或者中间件开发,你很难感受到AQS的威力.当然,学习很多时候,需要的是正向反馈,学了太多造火箭的东西,面试完就 ...
- 原创 | CRUD更要知道的Spring事务传播机制
来自:肥朝 AQS到底有什么用?难道就真的只是为了面试吗? 当然不是说AQS没用,如果你不是做基础架构或者中间件开发,你很难感受到AQS的威力.当然,学习很多时候,需要的是正向反馈,学了太多造火箭的东 ...
- Spring事务传播性与隔离级别
为什么80%的码农都做不了架构师?>>> 事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题. 事务最重要的两个特性,是事务的传 ...
- Spring事务传播特性实例解析
背景介绍 目前系统正在进行代码重构前期预研工作,目标采用spring控制事务以减少开发代码量,提高开发效率.同时避免开发人员编码控制事务所带来的链接没有释放,事务没有提交,出现异常事务没有回滚的Bug ...
- 实例详解 EJB 中的六大事务传播属性--转
前言 事务 (Transaction) 是访问并可能更新数据库中各种数据项的一个程序执行单元 (unit).在关系数据库中,一个事务可以是一条或一组 SQL 语句,甚至整个程序.它有通常被称为 ACI ...
- Spring事务传播行为详解
前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.这是Spring ...
- Spring的7种事务传播行为类型
1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置. 2.PROPAGATION_SUPPORTS:支持当前事务,如 ...
- Spring五个事务隔离级别和七个事务传播行为
Spring五个事务隔离级别和七个事务传播行为 1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数 ...
- 太难了~面试官让我结合案例讲讲自己对Spring事务传播行为的理解!
摘要: 原创出处 sf.gg/a/1190000013341344 「handaqiang」欢迎转载,保留摘要,谢谢! 前言 基础概念 1. 什么是事务传播行为? 2. Spring 中七种事务传播行 ...
- spring 事务隔离级别和传播行为_Spring事务传播实战
事务传播实战 事务具有四个特性 --ACID.其中 A 代表原子性,意思是一个事务要么成功(将结果写入数据库),要么失败(不对数据库有任何影响).这种方式在一个事务单打独斗的时候是一个非常好的做法,但 ...
最新文章
- SQL优化常用方法36
- ArcGIS中加载模块时dojo/domReady!和dojo/ready的区别
- “云原生”为什么对云计算生态充满吸引力?
- 输入一个正整数求所有素数因子_一起来聊聊素数的两个性质
- springboot 实现机器学习_SpringBoot架构浅谈
- java B2B2C Springcloud电子商务平台源码 -Feign之源码解析
- 一份数据工程师必备的学习资源,干货满满(附链接)
- Git储藏和引用日志
- 解决:应用程序无法启动,因为应用程序的并行配置不正确
- 通达信板块监控指标_通达信主力监控系统指标公式
- 华为初面+综合面试(Java技术面)附上面试题
- asp.net调用51ditu
- 推荐几个查找英语单词缩写的网站
- 0920-TCP断线重连 reconnect
- 《普陀区加快发展网络安全产业实施意见》的通知
- java禅道_使用Java+Excel统计禅道上问题处理情况
- 《华尔街》观后笔记8——明暗创新
- 盘点在未来,或许会被人工智能机器人取代的10种职业
- MinGW和MSYS简介
- 软考高项历年“风险”论文