spring中的事务处理配置

合集下载

Spring事务管理中@Transactional的参数配置

Spring事务管理中@Transactional的参数配置

Spring事务管理中@Transactional的参数配置Spring作为低侵⼊的Java EE框架之⼀,能够很好地与其他框架进⾏整合,其中Spring与Hibernate的整合实现的事务管理是常⽤的⼀种功能。

所谓事务,就必须具备ACID特性,即原⼦性、⼀致性、隔离性和持久性,在Hibernate的实现中,需要我们编写代码来完成事务的控制⼯作。

未使⽤Spring的事务管理12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public static void main(String[] args) {// Configuration cfg = new Configuration();// cfg.configure();// SessionFactory sf = cfg.buildSessionFactory();//因为在HibernateUtil类中已经有⼀部分封装⼯作,所以以上三⾏注释掉了。

Session s = null;Transaction tx = null;try{Class.forName("com.HibernateUtil");s = HibernateUtil.getSession();tx = s.beginTransaction(); //这⾥开启了事务//事务中所需的⼀系列数据库操作。

mit();} catch(HibernateException e) { //如果出现异常,且事务已经开启,则需要回滚。

if(tx != null)tx.rollback();throw e;} catch(ClassNotFoundException e) {e.printStackTrace();} finally{ //⽆论如何都需要关闭Session。

Spring事务配置的五种方式

Spring事务配置的五种方式

Spring事务原理统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatusspring提供了几个关于事务处理的类:TransactionDefinition //事务属性定义TranscationStatus //代表了当前的事务,可以提交,回滚。

PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。

一般事务定义步骤:TransactionDefinition td = new TransactionDefinition();TransactionStatus ts = transactionManager.getTransaction(td);try{ //do sthmit(ts);}catch(Exception e){transactionManager.rollback(ts);}spring提供的事务管理可以分为两类:编程式的和声明式的。

编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。

编程式主要使用transactionTemplate。

省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.void add(){transactionTemplate.execute( new TransactionCallback(){pulic Object doInTransaction(TransactionStatus ts){ //do sth}}}声明式:使用TransactionProxyFactoryBean:<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref bean="transactionManager"/></property><property name="target"><ref local="userManagerTarget"/></property><property name="transactionAttributes"><props><prop key="insert*">PROPAGATION_REQUIRED</prop><prop key="update*">PROPAGATION_REQUIRED</prop><prop key="*">PROPAGATION_REQUIRED,readOnly</prop></props></property></bean>围绕Poxy的动态代理能够自动的提交和回滚事务org.springframework.transaction.interceptor.TransactionProxyFactoryBeanPROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。

spring 事务 实现原理

spring 事务 实现原理

spring 事务实现原理Spring事务的实现原理主要依赖于数据库或者其他存储系统的事务功能。

1. 数据库事务支持:Spring事务的实现依赖于数据库的事务功能。

通常情况下,数据库支持ACID(原子性、一致性、隔离性和持久性)事务特性,可以通过SQL的BEGIN、COMMIT 和ROLLBACK等命令来控制事务的开始、提交和回滚操作。

2. 事务管理器:Spring框架提供了事务管理器(TransactionManager)接口,用于管理事务的开始、提交和回滚等操作。

事务管理器可以根据配置信息选择不同的实现,如使用JDBC事务管理器(DataSourceTransactionManager)或者JTA事务管理器(JtaTransactionManager)等。

3. 编程式事务:Spring框架提供了编程式事务管理的支持,通过编写代码显式地控制事务的边界。

开发者可以在代码中使用事务管理器的API来手动管理事务,包括事务的开始、提交和回滚等操作。

这种方式灵活性较高,但也需要开发者手动处理事务的细节。

4. 声明式事务:Spring框架还提供了声明式事务管理的支持,通过使用注解或者XML配置来定义事务的属性和边界。

开发者可以使用@Transactional注解或者事务配置元素来标记方法或者类,指示该方法或者类在执行时需要开启事务。

Spring会在方法调用前后自动地管理事务的开始、提交和回滚等操作。

5. 事务传播行为:Spring事务还支持事务传播行为的定义,即一个方法调用另一个带有事务的方法时事务该如何传播。

例如,当前方法可能会暂停事务、加入到现有的事务中或者创建一个新的事务。

Spring提供了多种事务传播行为的选项,如REQUIRED、REQUIRES_NEW、NESTED等,可以根据需要进行配置。

总的来说,Spring事务的实现原理是通过与数据库或其他存储系统的事务功能结合,通过事务管理器来管理事务的开始、提交和回滚等操作。

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用[转]spring,mybatis事务管理配置与@Transactional注解使用概述事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。

Spring Framework对事务管理提供了一致的抽象,其特点如下:为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更简单的编程式事务管理API与spring数据访问抽象的完美集成事务管理方式spring支持编程式事务管理和声明式事务管理两种方式。

编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。

对于编程式事务管理,spring推荐使用TransactionTemplate。

声明式事务管理建立在AOP之上的。

其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

显然声明式事务管理要优于编程式事务管理,这正是spring 倡导的非侵入式的开发方式。

声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。

和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

MyBatis-Spring-TransactionManager事务管理

MyBatis-Spring-TransactionManager事务管理
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
</bean>
编程式事务管理
MyBatis 的 SqlSession 提供指定的方法来处理编程式的事务。 但是当使用 MyBatis-Spring 时, bean 将会使用 Spring 管理的 SqlSession 或映射器来注入。 那就是说 Spring 通常是处理 事务的。
一旦事务创建之后,MyBatis-Spring 将会透明的管理事务。在你的 DAO 类中就不需要额 外的代码了。
标准配置
要 开 启 Spring 的 事 务 处 理 , 在 Spring 的 XML 配 置 文 件 中 简 单 创 建 一 个 DataSourceTransactionManager 对象:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
</bean>
指定的 DataSource 一般可以是你使用 Spring 的任意 JDBC DataSource。这包含了连接 池和通过 JNDI 查找获得的 DataSource。
要注意, 为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的 是同一个数据源,否则事务管理器就无法工作了。

SpringBoot多数据源配置事务

SpringBoot多数据源配置事务

SpringBoot多数据源配置事务在多数据源中配置事务,其实对于SpringBoot来很简单,当然这个的前提是⾸先把多数据源都配好的情况下,如果不会多数据源配置,请看该系列 SpringBoot整合多数据源⾸先在启动类配置@SpringBootApplication@EnableTransactionManagementpublic class AccountApplication {public static void main(String[] args) {SpringApplication.run(AccountApplication.class, args);}}当配置了这个事务注解,会⾃动去加载我们的事务Bean。

配置多个事务事务1@Bean(name = "accountTransactionManager")@Primarypublic PlatformTransactionManager testTransactionManager(@Qualifier("accountDataSource") DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);return dataSourceTransactionManager;}事务2@Bean(name = "otoSaaSTransactionManager")public PlatformTransactionManager testTransactionManager(@Qualifier("otoSaaSDataSource") DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);return dataSourceTransactionManager;}这个是时候就可以指定⽤哪个事务处理使⽤事务1@Override@Transactional(value = "accountTransactionManager",rollbackFor = Exception.class)public boolean insertAddMoney(String account, String quota) {...}使⽤事务2@Override@Transactional(value = "otoSaaSTransactionManager",rollbackFor = Exception.class)public boolean insertAddMoney(String account, String quota) {...}那么此时就产⽣了⼀个疑惑,在多数据源和事务管理器中,如果不指定默认返回的事务呢?怎么配置默认事务处理器呢?很简。

实验十四 Spring事务处理

实验十四 Spring事务处理

实验十四 Spring事务处理
一、实验目的
1.掌握基于注解管理事务的方式
2.熟悉基于XML配置方式管理事务
二、实验环境
1.Tomcat
2. MyEclipse
三、实验描述
Student的表结构(注:id为自动递增):
1.根据上述Student的表结构,使用注解管理事务的方式实现以下功能:
1)以新开一个事务的方式持久化两个Student实体到数据库表;
2)以只读事务方式读取id=1的实体;
3)必须要在一个事务中执行修改id=1的实体的姓名,否则抛出异常;
4)在默认的事务传播行为执行删除id=2的实体
5)在客户端调用执行各个方法,查看操作是否成功。

2.使用XML配置方式管理事务实现以上功能
四.实验步骤:
①创建一个java项目
②搭建Spring和Hibernate运行环境:把以下JAR文件构建到项目中
③编写持久化类及其映射文件
④创建一个Dao接口及其实现类
⑤创建一个业务接口及其实现类
⑥在src目录下新建一个Spring的配置文件
⑦创建测试类。

spring事务详解(基于注解和声明的两种实现方式)

spring事务详解(基于注解和声明的两种实现方式)

spring事务详解(基于注解和声明的两种实现⽅式)Spring事务( Transaction )事务的概念事务是⼀些sql语句的集合,作为⼀个整体执⾏,⼀起成功或者⼀起失败。

使⽤事务的时机⼀个操作需要多天sql语句⼀起完成才能成功程序中事务在哪⾥说明加在业务类的⽅法上⾯(public⽅法上⾯),表⽰业务⽅法执⾏时,需要事务的⽀持。

不同的事务管理器不同的数据库访问技术,处理事务是不同的1. 使⽤jdbc访问数据库,事务处理public void updateAccount(){Connection con = .....;con.setAutoCommit(false);state.insert();state.update();mit();con.setAutoCommit(true);}2. MyBatis执⾏数据库,处理事务public void updateAccount(){SqlSession sqlSession = SqlSessionFactory.openSession(false);try{sqlSession.insert(...);sqlSession.update(...);mit();}catch(Exception e){sqlSession.rollback();}}spring统⼀管理事务,把不同的数据库访问技术的事务处理统⼀起来使⽤spring的事务管理器,管理不同数据库访问技术的事务处理。

开发⼈员只需要掌握spring的事务处理⼀个⽅案,就可以实现使⽤不同数据库访问技术的事务管理。

尽管事务⾯向的是spring,有spring管理事务,做事务提交和回滚。

spring事务管理器spring框架使⽤事务管理器对象,管理所有的事务。

事务管理器接⼝: PlatFormTransactionManager作⽤:定义了事务的操作,主要是commit() , rollback()事务管理器有很多的实现类:⼀种数据库访问计数有⼀个实现类。

Spring声明式事务对注解配置的影响及其解决方案

Spring声明式事务对注解配置的影响及其解决方案
L I N Ye—y u, L I N Ya—mi n g
( D e p a r t m e n t o f C o m p u t e r S c i e n c e ,Mi n i f a n g U n i v e r s i t y ,F u z h o u 3 5 0 1 0 8 ,C h i n a )
第3 5卷
第 9期
宜春学院学报
J o u r n a l o f Yi c h u n C o l l e g e
V0 1 . 3 5. No . 9 S e p t . 2 0 1 3
2 0 1 3年 9月
S p r i n g声 明式 事 务对 注解 配 置 的影 响及 其 解 决 方 案
i t o r d e s i g n p a t t e r n— - b a s e d p r e s e n t a t i o n l a y e r c o d e i n f r a s t r u c t u r e i s p r o p o s e d a n d he t i mp l e me n t a t i o n d e t a i l s o f he t i n t e g r a t i o n o f Z K f r a me w o r k a n d S p r i n g t r a n s a c t i o n i s d i s c u s s e d, f or e x a mp l e . T h i s i n f r a s t r u c t u r e i s a b l e t o a v o i d
Ab s t r a c t :I n t h i s p a p e r ,f o u r c o mmo n l y u s e d me t h o d s f o r s o l v i n g l a z y l o a d i n g p r o b l e m or f he t S p in r g d e c l a r a t i v e

Spring多数据源事务配置问题

Spring多数据源事务配置问题

Spring多数据源事务配置问题第⼀步、测试能否配置多个DataSource第⼆步、测试能否配置多个SessionFactory第三步、测试能否配置多个TransactionManager第四步、测试能否使⽤多个TransactionManager,也就是看能否配置多个<tx:annotation-driven/>基本上到第四步就应该⾛不通了,因为Spring中似乎不能配置多个<tx:annotation-driven/>,⽽且@transactional注解也⽆法让⽤户选择具体使⽤哪个TransactionManager。

也就是说,在SpringSide的应⽤中,不能让不同的数据源分别属于不同的事务管理器,多数据源只能使⽤分布式事务管理器,那么测试思路继续如下进⾏:第五步、测试能否配置JTATransactionManager如果到这⼀步,项⽬还能顺利在Tomcat中运⾏的话,我们就算⼤功告成了。

但我总认为事情不会那么顺利,我总觉得JTATransactionManager需要应⽤服务器的⽀持,⽽且需要和JNDI配合使⽤,具体是不是这样,那只有等测试后才知道。

如果被我不幸⾔中,那么进⾏下⼀步:第六步、更换Tomcat为GlassFish,更换JDBC的DataSource为JNDI查找的DataSource,然后配置JTATransactionManager下⾯测试开始,先假设场景,还是继续⽤上⼀篇中提到的简单的⽂章发布系统,假设该系统运⾏⼀段时间后⾮常⽕爆,单靠⼀台服务器已经⽆法⽀持巨⼤的⽤户数,这时候,站长想到了把数据进⾏⽔平划分,于是,需要建⽴⼀个索引数据库,该索引数据库需保存每⼀篇⽂章的Subject及其内容所在的Web服务器,⽽每⼀个Web服务器上运⾏的项⽬,需要同时访问索引数据库和内容数据库。

所以,需要创建索引数据库,如下:create database puretext_index;use puretext_index;create table articles(id int primary key auto_increment,subject varchar(256),webserver varchar(30));第⼀步测试,配置多个DataSource,配置⽂件如下:application.properties:jdbc.urlContent=jdbc:mysql://localhost:3306/PureText?useUnicode=true&characterEncoding=utf8jdbc.urlIndex=jdbc:mysql://localhost:3306/PureText_Index?useUnicode=true&characterEncoding=utf8applicationContext.xml:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="mons.dbcp.BasicDataSource" destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="${jdbc.urlContent}"/><property name="username" value="${ername}"/><property name="password" value="${jdbc.password}"/><!-- Connection Pooling Info --><property name="initialSize" value="5"/><property name="maxActive" value="100"/><property name="maxIdle" value="30"/><property name="maxWait" value="1000"/><property name="poolPreparedStatements" value="true"/><property name="defaultAutoCommit" value="false"/></bean><bean id="dataSourceIndex" class="mons.dbcp.BasicDataSource" destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="${jdbc.urlIndex}"/><property name="username" value="${ername}"/><property name="password" value="${jdbc.password}"/><!-- Connection Pooling Info --><property name="initialSize" value="5"/><property name="maxActive" value="100"/><property name="maxIdle" value="30"/><property name="maxWait" value="1000"/><property name="poolPreparedStatements" value="true"/><property name="defaultAutoCommit" value="false"/></bean><!-- 数据源配置,使⽤应⽤服务器的数据库连接池 --><!--<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ExampleDB" />--><!-- Hibernate配置 --><bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSourceContent"/><property name="namingStrategy"><bean class="org.hibernate.cfg.ImprovedNamingStrategy"/></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop><prop key="hibernate.show_sql">${hibernate.show_sql}</prop><prop key="hibernate.format_sql">${hibernate.format_sql}</prop><prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop><prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.ehcache_config_file}</prop></props></property><property name="packagesToScan" value="cn.puretext.entity.*"/></bean><!-- 事务管理器配置,单数据源事务 --><bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"/></bean><!-- 事务管理器配置,多数据源JTA事务--><!--<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager orWebLogicJtaTransactionManager" />--><!-- 使⽤annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager"/></beans>这个时候运⾏上⼀篇⽂章中写好的单元测试DaoTest.java,结果发现还是会出错,错误原因如下:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cn.puretext.unit.service.DaoTest': Autowiring of methods failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests.setDataSource(javax.sql.DataSource); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: [dataSourceContent, dataSourceIndex]经过分析,发现是测试类的基类需要注⼊DataSource,⽽现在配置了多个DataSource,所以Spring不知道哪个DataSource匹配了,所以需要改写DaoTest.java,如下:package cn.puretext.unit.service;import java.util.List;import javax.annotation.Resource;import javax.sql.DataSource;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springside.modules.orm.Page;import org.springside.modules.test.junit4.SpringTxTestCase;import cn.puretext.dao.ArticleDao;import cn.puretext.entity.web.Article;public class DaoTest extends SpringTxTestCase {@Autowiredprivate ArticleDao articleDao;public ArticleDao getArticleDao() {return articleDao;}public void setArticleDao(ArticleDao articleDao) {this.articleDao = articleDao;}@Override@Resource(name = "dataSourceContent")public void setDataSource(DataSource dataSource) {// TODO Auto-generated method stubsuper.setDataSource(dataSource);}@Testpublic void addArticle() {Article article = new Article();article.setSubject("article test");article.setContent("article test");articleDao.save(article);}@Testpublic void pageQuery() {Page<Article> page = new Page<Article>();page.setPageSize(10);page.setPageNo(2);page = articleDao.getAll(page);List<Article> articles = page.getResult();}}改变的内容主要为重写了基类中的setDataSource⽅法,并使⽤@Resource注解指定使⽤的DataSource为dataSourceContent。

Spring声明式事务@Transactional详解,事务隔离级别和传播行为

Spring声明式事务@Transactional详解,事务隔离级别和传播行为

Spring声明式事务@Transactional详解,事务隔离级别和传播⾏为@Transactional注解⽀持9个属性的设置,这⾥只讲解其中使⽤较多的三个属性:readOnly、propagation、isolation。

其中propagation属性⽤来枚举事务的传播⾏为,isolation⽤来设置事务隔离级别,readOnly进⾏读写事务控制。

@Service@Transactional(readOnly = true)public class AppTradeRec2Service extends BaseService {@Autowiredprivate AppTradeRecDao appTradeRecDao;@Autowiredprivate ConsInfoDao consInfoDao;@Transactional(readOnly = false)public void payCharge(TradeRec tradeRec) {User usr = UserUtils.getUser();ConsInfo cons = consInfoDao.getByUser(usr.getId());//修改交易记录tradeRec.setPayBefore(cons.getAccountAmt());tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec.getRcvAmt());tradeRec.setIsPay("99");appTradeRecDao.save(tradeRec);//修改账户余额cons.setAccountAmt(cons.getAccountAmt() - tradeRec.getRcvAmt());consInfoDao.save(cons);}}⼀、readOnly读写事务控制readOnly=true表明所注解的⽅法或类只是读取数据。

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用[转]spring,mybatis事务管理配置与@Transactional注解使用概述事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。

Spring Framework对事务管理提供了一致的抽象,其特点如下:为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更简单的编程式事务管理API与spring数据访问抽象的完美集成事务管理方式spring支持编程式事务管理和声明式事务管理两种方式。

编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。

对于编程式事务管理,spring推荐使用TransactionTemplate。

声明式事务管理建立在AOP之上的。

其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

显然声明式事务管理要优于编程式事务管理,这正是spring 倡导的非侵入式的开发方式。

声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。

和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

spring中事务注解@Transactional与trycatch的使用

spring中事务注解@Transactional与trycatch的使用

spring中事务注解@Transactional与trycatch的使⽤spring事务注解@Transactional与trycatch在项⽬中 @service层中我们会经常在做⼀些增删改操作的⽅法上看到 spring 的事务注解 @transaction 已知@transaction 是让spring 帮我们实现事务的控制。

但是在项⽬中会经常看到有的⽅法中会存在trycatch块包括的⽅法上注解着@transactioneg:@Override@Transactionalpublic Json addOrder(TOrderAddReq tOrderAddReq) {try{//增删改⽅法} catch (Exception e) {.....e.printStackTrace();}// }return json;}上述的⽅法执⾏后可以看到事务并没有执⾏,接下来再看⼀个例⼦eg:@Override@Transactionalpublic Json addOrder(TOrderAddReq tOrderAddReq) {try{//增删改⽅法} catch (Exception e) {// ⼿动硬编码开启spring事务管理TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();e.printStackTrace();}// }return json;}上述⽅法执⾏后我们可以看到事务最后执⾏了,但实际上事务执⾏只是因为⼿动硬编码开启spring事务管理起了作⽤⽽⽅法上的注解并没有起作⽤接下来再看⼀个例⼦eg@Override@Transactionalpublic Json addOrder(TOrderAddReq tOrderAddReq) {try{//增删改⽅法} catch (Exception e) {throw new RuntimeException();}// }return json;}上述⽅法执⾏后我们可以看到事务是执⾏了的,但这⾥有个⼩细节:@Transactional不做任何配置默认是对抛出的unchecked 异常回滚,checked异常不会回滚,为了让所有异常都会让事务启动可以将 @Transactional配置为@Transactional(rollbackFor = Exception.class)解释:spring的事务边界是在调⽤业务⽅法之前开始的,业务⽅法执⾏完毕之后来执⾏commit or rollback(spring默认取决于是否抛出runtime异常).如果抛出runtime exception 并在你的业务⽅法中没有catch到的话,事务会回滚。

Spring中@Transactional用法详细介绍

Spring中@Transactional用法详细介绍

Spring中@Transactional⽤法详细介绍Spring中@Transactional⽤法详细介绍引⾔:在spring中@Transactional提供⼀种控制事务管理的快捷⼿段,但是很多⼈都只是@Transactional简单使⽤,并未深⼊了解,其各个配置项的使⽤⽅法,本⽂将深⼊讲解各个配置项的使⽤。

1. @Transactional的定义Spring中的@Transactional基于动态代理的机制,提供了⼀种透明的事务管理机制,⽅便快捷解决在开发中碰到的问题。

在现实中,实际的问题往往⽐我们预期的要复杂很多,这就要求对@Transactional有深⼊的了解,以来应对复杂问题。

⾸先我们来看看@Transactional的代码定义:@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Transactional {/*** A qualifier value for the specified transaction.* <p>May be used to determine the target transaction manager,* matching the qualifier value (or the bean name) of a specific* {@link org.springframework.transaction.PlatformTransactionManager}* bean definition.*/String value() default "";/*** The transaction propagation type.* Defaults to {@link Propagation#REQUIRED}.* @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()*/Propagation propagation() default Propagation.REQUIRED;/*** The transaction isolation level.* Defaults to {@link Isolation#DEFAULT}.* @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel()*/Isolation isolation() default Isolation.DEFAULT;/*** The timeout for this transaction.* Defaults to the default timeout of the underlying transaction system.* @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout()*/int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;/*** {@code true} if the transaction is read-only.* Defaults to {@code false}.* <p>This just serves as a hint for the actual transaction subsystem;* it will <i>not necessarily</i> cause failure of write access attempts.* A transaction manager which cannot interpret the read-only hint will* <i>not</i> throw an exception when asked for a read-only transaction.* @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()*/boolean readOnly() default false;/*** Defines zero (0) or more exception {@link Class classes}, which must be a* subclass of {@link Throwable}, indicating which exception types must cause* a transaction rollback.* <p>This is the preferred way to construct a rollback rule, matching the* exception class and subclasses.* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}*/Class<? extends Throwable>[] rollbackFor() default {};/*** Defines zero (0) or more exception names (for exceptions which must be a* subclass of {@link Throwable}), indicating which exception types must cause* a transaction rollback.* <p>This can be a substring, with no wildcard support at present.* A value of "ServletException" would match* {@link javax.servlet.ServletException} and subclasses, for example.* <p><b>NB: </b>Consider carefully how specific the pattern is, and whether* to include package information (which isn't mandatory). For example,* "Exception" will match nearly anything, and will probably hide other rules.* "ng.Exception" would be correct if "Exception" was meant to define* a rule for all checked exceptions. With more unusual {@link Exception}* names such as "BaseBusinessException" there is no need to use a FQN.* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}*/String[] rollbackForClassName() default {};/*** Defines zero (0) or more exception {@link Class Classes}, which must be a* subclass of {@link Throwable}, indicating which exception types must <b>not</b>* cause a transaction rollback.* <p>This is the preferred way to construct a rollback rule, matching the* exception class and subclasses.* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}*/Class<? extends Throwable>[] noRollbackFor() default {};/*** Defines zero (0) or more exception names (for exceptions which must be a* subclass of {@link Throwable}) indicating which exception types must <b>not</b>* cause a transaction rollback.* <p>See the description of {@link #rollbackForClassName()} for more info on how* the specified names are treated.* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}*/String[] noRollbackForClassName() default {};}基于源代码,我们可以发现在@Transactional,原来有这么多的属性可以进⾏配置,从⽽达到复杂应⽤控制的⽬的。

Spring事务管理及与mybatis整合的事务管理

Spring事务管理及与mybatis整合的事务管理

数据访问事务处理in Spring+Mybatis3.0事务---保证了用户的每一次操作都是可靠的,即使出现了异常的访问,也不至于破坏后台数据的完整性;Java事务简介事务必须符合ISO/IEC所定制的ACID原则1)A(atomicity):原子性在事务执行的过程中,任何的失败就将导致事务的任何修改失效,2)C(consistency):一致性事务回滚时,事务所执行的内容必须恢复到初始状态,即事务执行前的状态3)I(isolation):隔离性事务执行过程中对数据的修改,在提交之前的数据对其他事务不可见4)D(durability):持久性已经提交的数据在事务执行失败时,数据的状态都是正确的.事务分类:全局事务(分布式事务):由应用服务器来管理(如JTA),同时可以用于多个事务性的资源;本地事务本地事务和资源相关,主要通过JDBC来实现在实际应用中,存在一种容器管理事务,容器事务主要是由javaEE应用服务器提供,容器事务大多给予JTA完成,事实上这是在容器中覆盖了JDBC和JTA事务.事务特性分析(use spring)TransactionDefinition 接口来定义事务属性。

Code:public interface TransactionDefinition{int getIsolationLevel();int getPropagationBehavior();int getTimeout();boolean isReadOnly();}事务机制a)事务隔离级别隔离级别是指若干个并发的事务之间的隔离程度。

TransactionDefinition 接口中定义了五个表示隔离级别的常量:TransactionDefinition.ISOLATION_DEFAULT(默认值):表示使用底层数据库的默认隔离级别。

对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。

Spring七种事务传播行为与五种事务隔离级别

Spring七种事务传播行为与五种事务隔离级别

Spring七种事务传播⾏为与五种事务隔离级别⼀、事务的传播⾏为:通过Propagation定义:<!-- 配置事务通知 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 以⽅法为单位,指定⽅法应⽤什么事务属性:isolation:隔离级别 propagation:传播⾏为 read-only:是否只读--><tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/><!--上⾯的⽅式只适⽤单个⽅法,当我们业务有很多个⽅法都要操作事务时,则要配置很多个,可以使⽤下⾯的通配符配置⽅式--><tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>省略update.. detele.....</tx:attributes></tx:advice>readOnly:事务属性中的readOnly标志表⽰对应的事务应该被最优化为只读事务。

这是⼀个最优化提⽰。

在⼀些情况下,⼀些事务策略能够起到显著的最优化效果,例如在使⽤Object/Relational映射⼯具(如:或TopLink)时避免dirty checking(试图“刷新”)。

springboot中的声明式事务管理及编程式事务管理

springboot中的声明式事务管理及编程式事务管理

springboot中的声明式事务管理及编程式事务管理这⼏天在做⼀个功能,具体的情况是这样的: 项⽬中原有的⼏个功能模块中有数据上报的功能,现在需要在这⼏个功能模块的上报之后⽣成⼀条消息记录,然后⼊库,在写个接⼝供前台来拉取消息记录。

看到这个需求,⾸先想到的是使⽤AOP来实现了,然后,我去看了下现有功能模块中的代码,发现了问题,这些模块中的业务逻辑并没有放在service层来处理,直接在controller中处理了,controller中包含了两个甚⾄多个service处理,这样是不能保证事务安全的,既然这样,那么我们如何实现能保证事务安全呢。

我想直接在controller中定义切⼊点,然后before中⼿动开启事务,在afterReturn之后根据需要来提交或者回滚事务。

然后趁着这个机会就查了下spring boot中的事务这块,就从最基础的说起。

1.spring boot中声明式事务的使⽤ 想要在spring boot中使⽤声明式事务,有两种⽅式,⼀种是在各个service层中添加注解,还有⼀种是使⽤AOP配置全局的声明式事务管理 先来说第⼀种,需要⽤到两个注解就,⼀个是@EnableTransactionManagement⽤来开启注解事务管理,等同于xml配置⽅式的 <tx:annotation-driven />,另⼀个是@Transactional 具体代码如下:1package com.example.demo;23import org.springframework.boot.SpringApplication;4import org.springframework.boot.autoconfigure.SpringBootApplication;5import org.springframework.transaction.annotation.EnableTransactionManagement;67// @SpringBootApplication是Sprnig Boot项⽬的核⼼注解,主要⽬的是开启⾃动配置10 @SpringBootApplication11 @EnableTransactionManagement // 启注解事务管理,等同于xml配置⽅式的 <tx:annotation-driven />12public class DemoApplication {14public static void main(String[] args) {16 SpringApplication.run(DemoApplication.class, args);18 }1920 } 然后,注解@Transactional直接加在service层就可以了,放两个service⽤来验证事务是否按预期回滚package com.example.demo.service;import com.example.demo.bean.ResUser;import org.springframework.transaction.annotation.Transactional;import java.util.List;/*** 注解加在接⼝上表名接⼝的所有⽅法都⽀持事务;* 如果加在⽅法上,则只有该⽅法⽀持事务* 可以根据需要在CUD操作上加注解**/@Transactionalpublic interface IUserService {int insertUser(ResUser resUser);int updateUser(ResUser resUser);List<ResUser> getResUserList();}1package com.example.demo.service;23import com.example.demo.bean.ResPartner;4import org.springframework.transaction.annotation.Transactional;56import java.util.List;7import java.util.Map;89 @Transactional10public interface IPartnerService {1112int add(ResPartner resPartner);1314int deleteByIds(String ids);1516int update(ResPartner resPartner);1718 ResPartner queryById(int id);1920 List<ResPartner> queryList(Map<String, Object> params);2122 } 实现类1package com.example.demo.service.impl;23import com.example.demo.bean.ResPartner;4import com.example.demo.dao.PartnerMapperXml;5import com.example.demo.service.IPartnerService;6import org.slf4j.Logger;7import org.slf4j.LoggerFactory;8import org.springframework.beans.factory.annotation.Autowired;9import ponent;1011import java.util.List;12import java.util.Map;1314 @Component("partnerService")15public class PartnerServiceImpl implements IPartnerService {1617private Logger logger = LoggerFactory.getLogger(this.getClass());18 @Autowired19private PartnerMapperXml partnerMapperXml;2021 @Override22public int add(ResPartner resPartner) {23 StringBuilder sbStr = new StringBuilder();24 sbStr.append("id = ").append(resPartner.getId())25 .append(", name = ").append(resPartner.getName())26 .append(", city = ").append(resPartner.getCity())27 .append(", displayName = ").append(resPartner.getDisplayName());(sbStr.toString());29return this.partnerMapperXml.add(resPartner);30 }31 }1package com.example.demo.service.impl;23import com.example.demo.bean.ResPartner;4import com.example.demo.bean.ResUser;5import com.example.demo.dao.PartnerMapperXml;6import com.example.demo.dao.ResUserMapper;7import com.example.demo.service.IUserService;8import org.springframework.beans.factory.annotation.Autowired;9import ponent;1011import java.util.List;1213 @Component("userService")14public class UserServiceImpl implements IUserService {1516 @Autowired17private ResUserMapper resUserMapper;18 @Autowired19private PartnerMapperXml partnerMapperXml;2021 @Override22public int insertUser(ResUser resUser) {2324int i = resUserMapper.insert(resUser);25// ResPartner partner = new ResPartner();26// partner.setId(resUser.getId());27// partner.setName(resUser.getName());28// partner.setDisplayName(resUser.getLogin());29//30// if (true) // ⽤来验证异常,使事务回滚31// throw new RuntimeException("xxxxxxxxxxxxxxx");32// int a = 1/0;33// partnerMapperXml.add(partner);3435return i;36 }3738 } controller代码,JSONMsg是⼀个⾃定义类,就三个属性code,msg,data⽤来给前台返回数据。

springBootservice层事务控制的操作

springBootservice层事务控制的操作

springBootservice层事务控制的操作springBoot使⽤事物⽐较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的⽅法上添加@Transactional注解@Transactional属性属性类型描述value String可选的限定描述符,指定使⽤的事务管理器propagation enum: Propagation可选的事务传播⾏为设置isolation enum: Isolation可选的事务隔离级别设置readOnly boolean读写或只读事务,默认读写timeout int (in seconds granularity)事务超时时间设置rollbackFor Class对象数组,必须继承⾃Throwable导致事务回滚的异常类数组rollbackForClassName类名数组,必须继承⾃Throwable导致事务回滚的异常类名字数组noRollbackFor Class对象数组,必须继承⾃Throwable不会导致事务回滚的异常类数组noRollbackForClassName类名数组,必须继承⾃Throwable不会导致事务回滚的异常类名字数组⽤法:@Transactional 可以作⽤于接⼝、接⼝⽅法、类以及类⽅法上。

当作⽤于类上时,该类的所有 public ⽅法将都具有该类型的事务属性,同时,我们也可以在⽅法级别使⽤该标注来覆盖类级别的定义。

虽然 @Transactional 注解可以作⽤于接⼝、接⼝⽅法、类以及类⽅法上,但是 Spring 建议不要在接⼝或者接⼝⽅法上使⽤该注解,因为这只有在使⽤基于接⼝的代理时它才会⽣效。

另外, @Transactional 注解应该只被应⽤到 public ⽅法上,这是由 Spring AOP 的本质决定的。

如果你在 protected、private 或者默认可见性的⽅法上使⽤ @Transactional 注解,这将被忽略,也不会抛出任何异常。

springboot整合多数据源以及多数据源中的事务处理

springboot整合多数据源以及多数据源中的事务处理

springboot整合多数据源以及多数据源中的事务处理前⾔本篇⽂章主要介绍的是springboot整合多数据源以及多数据源事务处理。

多数据源就是在同⼀个项⽬中连接多个数据库,使⽤多个数据库可能是由于业务量扩⼤进⾏数据库拆分,也可能是根据项⽬实际情况需要连接多个数据库。

⽐如我之前有个项⽬,需要访问⼀个已有的数据库进⾏查询操作,但不能修改,还需要新建数据库表进⾏其他的业务处理,这时就需要使⽤多数据源。

GitHub源码链接位于⽂章底部。

创建数据库创建member数据库,添加⼀张user表,字段为id主键⾃增,name,age;创建order数据库,添加⼀张order表,字段为id主键⾃增,number;⼯程结构先来看⼀下⼯程结构,这⾥的demo使⽤会员数据库和订单数据库,建⽴member和order相关包和类。

引⼊依赖在pom⽂件中引⼊依赖,这⾥持久层框架使⽤的是mybatis,数据库引擎是mysql。

不过oracle也适⽤。

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MySQL 连接驱动依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.39</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency></dependencies>yml配置在application.yml中进⾏数据源配置server:port: 8080spring:datasource:member:jdbc-url: jdbc:mysql://localhost:3306/member?useUnicode=true&characterEncoding=utf-8username: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverorder:jdbc-url: jdbc:mysql://localhost:3306/order?useUnicode=true&characterEncoding=utf-8username: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driver这⾥数据源的url的key是'jdbc-url',在多数据源的情况下,使⽤'url'作为key会报错,这是它本⾝的⼀个bug。

transactional的rollbackfor参数 -回复

transactional的rollbackfor参数 -回复

transactional的rollbackfor参数-回复什么是transactional的rollbackFor参数?为什么要使用它?如何正确地配置它?在实际开发中如何应用它?这些都是开发中常见的问题。

在本文中,我们将一步一步回答这些问题,以帮助读者更好地理解和应用transactional的rollbackFor参数。

当我们使用Spring Framework进行开发时,经常会涉及到数据库事务的处理。

数据库事务是一组数据库操作的有序执行,要么全部执行成功,要么全部回滚到事务开始的状态。

Spring的transactional注解就是用于管理数据库事务的关键之一。

在Spring的transactional注解中,rollbackFor参数是一个非常重要的配置项。

它用来指定在哪些异常发生时,事务应该进行回滚。

默认情况下,Spring只会对RuntimeException进行回滚,但是对于受检查异常(Checked Exceptions)默认不会回滚。

这时就需要使用rollbackFor 参数来指定我们想要回滚的异常类型。

首先,让我们来看看为什么我们需要使用rollbackFor参数。

在实际开发中,通常会遇到数据库操作异常或业务逻辑异常。

例如,当插入数据库时,由于某些原因,数据库连接断开,此时插入会抛出SQLException。

如果我们不配置rollbackFor参数,Spring默认不会回滚事务,导致插入的数据无效。

为了解决这个问题,我们可以在transactional注解中使用rollbackFor参数来指定回滚的异常类型。

通过配置该参数,当指定的异常发生时,Spring会自动回滚事务,防止数据失效。

在上述例子中,我们可以使用rollbackFor = SQLException.class来配置rollbackFor参数。

接下来,让我们来看看如何正确地配置rollbackFor参数。

正常情况下,我们只需要在transactional注解中指定rollbackFor参数的值即可。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
<property name="transactionInterceptor" ref="transactionInterceptor" />
</bean>
该自动代理的意思是,所有以Service的bean,都是需要使用该拦截器。
以下是ServiceBean的配置
<bean id="userService" class="erServiceImpl" autowire="byName">
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
<props>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="move*">PROPAGATION_REQUIRED</prop>
</property>
</bean>
这种声明方式我足足用了两年,自从与李刚才师接触后,买了在他著作的《Spring 2.0宝典》,学习之后,发现原来Spring也可以这么配置
基于AOP技术的事务处理方式,首先声明一个事务的拦截器
<bean id="transactionInterceptor"
<bean class="erServiceImpl">
<property name="userDAO"><ref bean="userDAO"/></property>
</bean>
<property name="userDAO" ref="userDAO" />
</bean>
这种配置方式简单得多,虽然对于有些程序员觉得使用copy & paste,其实都是一差不多,但是,配置文件至少可以少一大半,方便维护!
</property>
</bean>
接着,声明一个service类,使用Spring的事务处理模板
<bean id="userService" parent="txProxyTemplate">
<property name="target">
Spring的事务处理机制,给我们编程带来了极大的方便,One-Transaction-Per-Request的实现模式,是本人最为欣赏的!
在之前开始接触Spring的时候,为了实现事务处理的模式,我们在声明事务的时候,一般是这么做
首先声明一个事务模板,
<bean id="txProxyTemplate" abstract="true"
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<y name="beanNames">
<value>*Service</value>
</property>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
接着,声明一个自动代理
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
</property>
<property name="transactionAttributes">
<props>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
相关文档
最新文档