Spring事务管理高级应用难点剖析(3)
Spring声明式事务详解
Spring声明式事务详解Spring 中的事务控制⽅式Spring 的事务控制可以分为编程式事务控制和声明式事务控制编程式开发者直接把事务的代码和业务代码耦合到⼀起,在实际开发中不⽤。
声明式开发者采⽤配置的⽅式来实现的事务控制,业务代码与事务代码实现解耦合,使⽤的API思想。
基于XML的声明式事务控制【重点】在 Spring配置⽂件中声明式的处理事来代替代码式的处理事务。
底层采⽤ AOP 思想来实现的。
声明式事务控制明确事项:核⼼业务代码(⽬标对象)事务增强代码{ Spring已提供事务管理器)切⾯配置步骤分析1.引⼊tx 命名空间2.事务管理器通知配置3.事务管理器AOP配置引⼊依赖坐标<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xsi:schemaLocation="/schema/beanshttps:///schema/beans/spring-beans.xsd/schema/contexthttps:///schema/context/spring-context.xsd/schema/aophttps:///schema/aop/spring-aop.xsd/schema/txhttps:///schema/tx/spring-tx.xsd"></beans>基于 XML 的声明式事务的控制配置⽂件<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xsi:schemaLocation="/schema/beanshttps:///schema/beans/spring-beans.xsd/schema/contexthttps:///schema/context/spring-context.xsd/schema/aophttps:///schema/aop/spring-aop.xsd/schema/txhttps:///schema/tx/spring-tx.xsd"><!-- 开启 IOC 注解扫描 --><context:component-scan base-package="inly"/><!-- 引⼊ properties ⽂件 --><context:property-placeholder location="classpath:jdbc.properties"/><!-- 配置数据源 --><bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${ername}"/><property name="password" value="${jdbc.password}"/></bean><!-- jdbcTemplate --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!-- 绑定数据源 --><property name="dataSource" ref="datasource"/></bean><!-- 事务管理器对象 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源对象 --><property name="dataSource" ref="datasource"/></bean><!-- 通知增强 transaction-manager: 配置的事务管理器对象 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 定义⼀些事务属性 --><tx:attributes><!-- * 表⽰当前任意名称的⽅法都⾛默认的配置 --><tx:method name="*"/></tx:attributes></tx:advice><!-- AOP 配置切⾯ --><aop:config><!-- 配置声明式式务 --><aop:advisor advice-ref="txAdvice" pointcut="execution(* erServiceImpl.updateUser(..))"/></aop:config></beans>Service 层@Overridepublic void updateUser() {User user = userDao.find(2);user.setName("li3");userDao.updateUser(user);int i = 1 / 0;user.setAge(13);userDao.updateUser(user);System.out.println(user);}事务参数的配置详解<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/> name:切点⽅法等isolation:事务的隔离级别propogation:事务的传播⾏为timeout:超时时间read-only:是否只读常⽤ CURD 配置<tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 定义⼀些事务属性 --><tx:attributes><!-- CRUD 常⽤配置表⽰以update开头的⽅法--><tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/> <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/><tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/> <tx:method name="find" read-only="true"/><!-- * 表⽰当前任意名称的⽅法都⾛默认的配置 --><tx:method name="*"/></tx:attributes></tx:advice>基于注解的声明式事务控制常⽤注解步骤分析修改 Service 层,增加事务注解@Override@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,readOnly = false,timeout = -1) public void updateUser() {User user = userDao.find(2);user.setName("li3");userDao.updateUser(user);int i = 1 / 0;user.setAge(13);userDao.updateUser(user);System.out.println(user);}修改 Spring 核⼼配置⽂件,开启事务注解⽀持<tx:annotation-driven/>。
spring事务管理总结
spring事务管理总结项目中一直用spring,事务管理这块还是遇到了挺多问题。
下面把这些问题总结一下,以供大家参考和讨论。
下面先提出这些问题问题一:spring中的声明式事务很方便,但有时候还是不能很好的满足需求。
比如:项目中一些业务数据要从Excel中导入,一次导入可能上千条,每一条数据又涉及多个表(这几个表的数据需要在一个事务中)。
这种情况可能声明式事务就不好办了。
问题二:“PROPAGA TION_REQUIRED,readOnly”,只读事务和“PROPAGATION_REQUIRED”区别在哪里?问题三:事务放在service层中,service中这个类的方法之间的调用,事务是什么样的?service 层调用另外一个service层的类的方法,事务又是怎样的?问题四:编程式事务中,多次提交报错:Transaction is already completed do not call commit or rollback more than once per transaction,如何解决?首先来看一下spring中事务的基本知识事务的属性(1) 传播行为PROPAGATION_MANDATORY: 方法必须在一个现存的事务中进行,否则丢出异常PROPAGATION_NESTED: 在一个嵌入的事务中进行,如果不是,则同PROPAGATION_REQUIREDPROPAGATION_NEVER: 指出不应在事务中进行,如果有就丢出异常PROPAGATION_NOT_SUPPORTED: 指出不应在事务中进行,如果有就暂停现存的事务PROPAGATION_REQUIRED: 在当前的事务中进行,如果没有就建立一个新的事务PROPAGATION_REQUIRES_NEW: 建立一个新的事务,如果现存一个事务就暂停它PROPAGATION_SUPPORTS: 支持现在的事务,如果没有就以非事务的方式执行(2) 隔离层级ISOLATION_DEFAULT: 使用底层数据库预设的隔离层级ISOLATION_READ_COMMITTED: 允许事务读取其他并行的事务已经送出(Commit)的数据字段,可以防止Dirty read问题ISOLATION_READ_UNCOMMITTED: 允许事务读取其他并行的事务还没送出的数据,会发生Dirty、Nonrepeatable、Phantom read等问题ISOLATION_REPEATABLE_READ: 要求多次读取的数据必须相同,除非事务本身更新数据,可防止Dirty、Nonrepeatable read问题ISOLATION_SERIALIZABLE: 完整的隔离层级,可防止Dirty、Nonrepeatable、Phantom read 等问题,会锁定对应的数据表格,因而有效率问题具体知识请看这篇文章,进一步了解spring事务请看这篇文章。
J2EE项目实训 Spring框架技术——第9章 Spring中的事务管理技术及实现(第1部分)
Connection conn = DriverManager.getConnection("URL","userName","userPassWord");
con.setAutoCommit(false); PreparedStatement pstmt1 = con.prepareStatement(insertUserInfoSql); pstmt1.setString(1,oneRegisterUserInfo.getUserName()); pstmt1.setString(2,oneRegisterUserInfo.getUserPassWord()); pstmt1.setInt(3,oneRegisterUserInfo.getUserType()); pstmt1.setString(4,oneRegisterUserInfo.getAliaoName()); pstmt1.setString(5,oneRegisterUserInfo.getPassWordAsk()); pstmt1.setString(6,oneRegisterUserInfo.getUserImage()); pstmt1.setString(7,oneRegisterUserInfo.getRegisterTime());
杨教授工作室,版权所有,盗版必究, 2/14 页
Spring中的事务管理实例详解
Spring中的事务管理实例详解本文实例讲述了Spring中的事务管理。
分享给大家供大家参考。
具体分析如下:事务简介:事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性事务就是一系列的动作,它们被当作一个单独的工作单元。
这些动作要么全部完成,要么全部不起作用事务的四个关键属性(ACID)①原子性(atomicity):事务室一个原子操作,有一系列动作组成。
事务的原子性确保动作要么全部完成,要么完全不起作用②一致性(consistency):一旦所有事务动作完成,事务就被提交。
数据和资源就处于一种满足业务规则的一致性状态中③隔离性(isolation):可能有许多事务会同时处理相同的数据,因此每个事物都应该与其他事务隔离开来,防止数据损坏④持久性(durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响。
通常情况下,事务的结果被写到持久化存储器中Spring中的事务管理作为企业级应用程序框架,Spring在不同的事务管理API之上定义了一个抽象层。
而应用程序开发人员不必了解底层的事务管理API,就可以使用Spring的事务管理机制。
Spring既支持编程式事务管理,也支持声明式的事务管理编程式事务管理:将事务管理代码嵌入到业务方法中来控制事务的提交和回滚,在编程式事务中,必须在每个业务操作中包含额外的事务管理代码声明式事务管理:大多数情况下比编程式事务管理更好用。
它将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。
事务管理作为一种横切关注点,可以通过AOP方法模块化。
Spring通过Spring AOP框架支持声明式事务管理。
Spring事务的传播属性:当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。
例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
事务的传播行为可以由传播属性指定。
Spring定义了7种传播行为:Spring支持的事务传播行为传播行为含义PROPAGATION_MANDATORY 表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常PROPAGATION_NESTED 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。
详解spring事务属性
您还未登录 ! 我的应用 登录 注册论坛首页 → Java 编程和Java 企业应用版 → Spring →详解spring 事务属性 全部 Hibernate Spring Struts iBATIS 企业应用 设计模式 DAO 领域模型 OO Tomcat SOA JBoss Swing Java 综合« 上一页 1 2 3 4 5 下一页 »浏览 61653 次锁定老帖子 主题:详解spring 事务属性该帖已经被评为良好帖作者 正文∙klyuan∙等级:∙∙ 性别:∙ 文章:201∙ 积分:502∙ 来自:深圳∙ 相关文章:∙ spring 事务详解∙ Spring 声明式事物管理详解∙ 解惑 spring 嵌套事务 推荐圈子: struts2 更多相关推荐 Spring 声明式事务让我们从复杂的事务处理中得到解脱。
使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。
再也无需要我们在与事务相关的方法中处理大量的try…catch…finally 代码。
我们在使用Spring 声明式事务时,有一个非常重要的概念就是事务属性。
事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。
我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。
Spring 在TransactionDefinition 接口中定义这些属性,以供PlatfromTransactionManager 使用,PlatfromTransactionManager 是spring 事务管理的核心接该帖已经被评为良好帖作者正文口。
TransactionDefinitionpublic interface TransactionDefinition {int getPropagationBehavior();int getIsolationLevel();int getTimeout();boolean isReadOnly();}getTimeout()方法,它返回事务必须在多少秒内完成。
应用Spring框架中的事务管理应用技术
(4)Spring声明式事务管理和EJB CMT的不同之处
不象 EJB CMT 绑定在 JTA 上, Spring 声明式事务管理可 以在任何环境下使用;同时,我们只需更改配置文件, 它就可以和 JDBC 、JDO 、 Hibernate 或其它的事务实现 的机制一起工作,相互集成在一起。 Spring 可以使声明式事务管理应用到普通 Java 对象, 不仅仅是特殊的类,如EJB组件类。 Spring 允许我们通过 AOP 定制事务行为。如果我们的 应用系统需要此功能,我们则可以在事务回滚中插入 定制的行为。
Spring提供声明式回滚规则:EJB没有对应的特性
7、声明控制的事务管理的优点
8、Spring中事务管理的一些相关类
注意: PlatformTransactionManager接口的应用
9、PlatformTransactionManager接口 (1)该接口的定义
(2)在该接口中定义了如下对事务控制的各个方法
(3)这样的设计方案给应用本身带来了以下优点
为复杂的事务 API 提供了一致的编程模型,如 JTA 、 JDBC、Hibernate、JPA和JDO 并支持声明式事务管理 提供比大多数复杂的事务API(诸如JTA)更简单的, 更易于使用的编程式事务管理API 非常好地整合Spring的各种数据访问抽象,并在不同 形式的数据访问组件中以统一的方式来应用 Spring中 的事务管理技术。
Байду номын сангаас
Spring使用注解对事务控制详解与实例
Spring使⽤注解对事务控制详解与实例1.什么是事务⼀荣俱荣,⼀损俱损,很多复杂的操作我们可以把它看成是⼀个整体,要么同时成功,要么同时失败。
事务的四个特征ACID:原⼦性(Atomic):表⽰组成⼀个事务的多个数据库的操作的不可分割的单元,只有所有的操作成功才算成功,整个事务提交,其中任何⼀个操作失败了都是导致整个所有操作失败,事务会回滚。
⼀致性(Consistentcy):事务操作成功后,数据库所处的状态和业务规则⼀致。
如果A账户给B账户汇100,A账户减去100,B加上100,两个账户的总额是不变的。
隔离性(islation):在多个数据库的操作相同的数据并发时,不同的事务有⾃⼰的数据空间,事务与事务之间不受⼲扰(不是绝对的)。
⼲扰程度受数据库或者操作事务的隔离级别来决定,隔离级别越⾼,⼲扰就越低,数据的⼀致性越好,并发性就越差。
持久性(Druability):⼀旦事务提交成功,数据就被持久化到数据库,不可以回滚。
2.spring使⽤注解对事务的控制 Spring 事务管理有两种⽅式:编程式事务管理、声明式事务管理 编程式事务管理通过TransactionTemplate⼿动管理事务,在实际应⽤中很少使⽤,我们来重点学习声明式事务管理 声明式事务管理有三种实现⽅式:基于TransactionProxyFactoryBean的⽅式、基于AspectJ的XML⽅式、基于注解的⽅式 1. 新建⼀个java⼯程——导⼊spring 和事务管理所需要的jar ——然后选择全部jar 右键Build path ——最后如图(我的java版本jre是1.8)2.在src⽬录下新建5个包如图 dao :数据连接层,主要⽤于存放对数据进⾏操作的类 model:模型层,主要⽤于存放实体类 service:服务层,主要⽤于对数据连接层进⾏操作的⼀些服务类。
util:⼯具类,主要⽤于存储⼯具⽅法 test:⽤于测试类3.在dao数据连接层,建⽴⾥与数据库操作的类与对应的接⼝(Order 订单,detail订单明细) 3.1 定义detailDao接⼝ 代码如下:1package com.spring.dao;23import com.spring.model.Detail;4import com.spring.model.Order;56public interface detailDao {7//保存订单明细8public void saveDetail(Detail detail);9101112 } 3.2 定义OrderDao接⼝代码如下:1package com.spring.dao;23import com.spring.model.Order;45public interface OrderDao {6//保存订单7public void saveOrder(Order order);891011 } 3.3 实现以上接⼝detailDaoImp 代码如下:1package com.spring.dao;23import javax.sql.DataSource;45import org.springframework.jdbc.core.JdbcTemplate;67import com.spring.model.Detail;8import com.spring.model.Order;910public class detailDaoImp implements detailDao {1112private DataSource dataSource;13private JdbcTemplate jdbcTemplate;1415public void setDataSource(DataSource dataSource) {16this.dataSource = dataSource;17this.jdbcTemplate = new JdbcTemplate(dataSource);18 }19//保存订单明细20public void saveDetail(Detail detail) {21 String SQL = "insert into t_detail values(null,?,?,?))";22 jdbcTemplate.update(SQL, new Object[] { detail.getItemName(),detail.getQuantity(),detail.getOrderId() });23 System.out.println("Insert detail success!");24 }2526 }OrderDaoImp代码如下:package com.spring.dao;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;import com.spring.model.Order;public class OrderDaoImp implements OrderDao {private DataSource dataSource;private JdbcTemplate jdbcTemplate;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;this.jdbcTemplate = new JdbcTemplate(dataSource);}//插⼊订单public void saveOrder(Order order) {String SQL = "insert into t_order values (null,?)";System.out.println(SQL);System.out.println(order.getTotal_price());jdbcTemplate.update(SQL, new Object[]{order.getTotal_price()});System.out.println("Insert order success!");}}4.在model层中新建两个实体类 (Order订单类,detail订单明细类) Order订单类代码如下:1package com.spring.model;23/*4 * 订单表5*/6public class Order {7//订单编号8private Integer order_id;9//订单总⾦额10private Integer total_price;11public Integer getOrder_id() {12return order_id;13 }14public void setOrder_id(Integer order_id) {15this.order_id = order_id;16 }17public Integer getTotal_price() {18return total_price;19 }20public void setTotal_price(Integer total_price) {21this.total_price = total_price;22 }23 } detail订单明细类代码如下:1package com.spring.model;23/**4 * 商品明细表5 * @author Administrator6 *7*/8public class Detail {9//ID10private Integer detailId;11//外键 暂时可以忽略12private Integer orderId;13public Integer getDetailId() {14return detailId;15 }16public void setDetailId(Integer detailId) {17this.detailId = detailId;18 }19public Integer getOrderId() {20return orderId;21 }22public void setOrderId(Integer orderId) {23this.orderId = orderId;24 }25public Integer getQuantity() {26return quantity;27 }28public void setQuantity(Integer quantity) {29this.quantity = quantity;30 }31public String getItemName() {32return itemName;33 }34public void setItemName(String itemName) {35this.itemName = itemName;36 }37//商品数量38private Integer quantity;39//商品数量40private String itemName;4142 }5.在service中定义⼀个接⼝并且实现它 OrderService代码如下:1package com.spring.service;3import com.spring.model.Detail;4import com.spring.model.Order;56public interface OrderService {7//插⼊订单和订单明细8public void saveOrderAndDetail(Order order,Detail detail);9 } OrderServiceImp代码如下:1package com.spring.service;23import org.springframework.transaction.annotation.Transactional;45import com.spring.dao.OrderDaoImp;6import com.spring.dao.detailDaoImp;7import com.spring.model.Detail;8import com.spring.model.Order;910/**11 * 服务层使⽤注解来实现事务管理12 *13 * @author Administrator14 *15*/1617public class OrderServiceImp implements OrderService {18// 注⼊两个对象19public OrderDaoImp OrderDaoImp;2021public detailDaoImp detailDaoImp;2223 @Transactional24 @Override25// 如果加上@Transaction时,⽅法执⾏有异常,整个事务数据都会回滚,数据库中不会存在有数据。
spring事务管理全解析
spring事务管理全解析事务是一组原子(Atomic)操作的工作单元,以数据库存取的实例来说,就是一组SQL指令,这一组SQL指令必须全部执行成功,若因为某个原因未全部执行成功(例如其中一行SQL有错误),则先前所有执行过的SQL指令都会被撤消。
JDBC是如何控制事务的try ...{.....connection.setAutoCommit(false);.....// 一连串SQL操作mit();} catch(SQLException) ...{// 发生错误,撤消所有变更connection.rollback();}Spring是把JDBC事务管理进来了封装,Spring事务管理的抽象关键在于org.springframework.transaction.PlatformTransactionManager接口里面有commit 和rollbackpublic interface PlatformTransactionManager ...{TransactionStatus getTransaction(TransactionDefinitiondefinition) throws TransactionException;void commit(TransactionStatus status)throws TransactionException;void rollback(TransactionStatus status)throws TransactionException;}TransactionDefinition接口的实例定义了事务的隔离程度(Isolation level)传播行为(Propagation behavior)超时(Timeout)只读(Read-only)等DataSourceTransactionManager、HibernateTransactionManager、JdoTransaction- Manager、JtaTransactionManager等是实现了该接口Spring提供编程式的事务管理(Programmatic transaction management)与声明式的事务管理(Declarative transaction management):1、编程式的事务管理可以清楚地控制事务的边界,也就是让您自行实现事务开始时间、撤消操作的时机、结束时间等,可以实现细粒度的事务控制。
宝贝,来,讲讲spring事务有哪些坑?
宝贝,来,讲讲spring事务有哪些坑?引言今天,我们接上文《面试官:谈谈你对mysql事务的认识》的内容,来讲spring中和事务有关的考题!因为事务这块,面试的出现几率很高。
而大家工作中CRUD的比较多,没有好好总结过这块的知识,因此面试容易支支吾吾答不出来,于是乎接下来你就会接到一张好人卡,如'你很优秀,不适合我们公司!'由于《面试官:谈谈你对mysql事务的认识》篇幅所限,因此略过了spring事务相关常见面试题,今天给大家补上!主要题目如下:•(1)spring事务的原理?•(2)spring什么情况下进行事务回滚?•(3)spring事务什么时候失效?•(4)Spring的事务和数据库的事务隔离是一个概念么?•(5)spring事务控制放在service层,在service方法中一个方法调用service中的另一个方法,默认开启几个事务?•(6)怎么保证spring事务内的连接唯一性?正文1、spring事务的原理?首先,我们先明白spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。
那么,我们一般使用JDBC操作事务的时候,代码如下•(1)获取连接Connection con = DriverManager.getConnection()•(2)开启事务con.setAutoCommit(true/false);•(3)执行CRUD•(4)提交事务/回滚事务 mit() / con.rollback();•(5)关闭连接 conn.close();使用spring事务管理后,我们可以省略步骤(2)和步骤(4),就是让AOP帮你去做这些工作。
关键类在TransactionAspectSupport这个切面里,大家有兴趣自己去翻。
我就不列举了,因为公众号类型的文章,实在不适合写一些源码解析!2、spring 什么情况下进行事务回滚?首先,我们要明白Spring事务回滚机制是这样的:当所拦截的方法有指定异常抛出,事务才会自动进行回滚!因此,如果你默默的吞掉异常,像下面这样@Servicepublic class UserService{@Transactionalpublic void updateUser(User user) {try {System.out.println('孤独烟真帅');//do something} catch {//do something}}}那切面捕捉不到异常,肯定是不会回滚的。
Spring框架事务管理应用分析
Spring框架事务管理应用分析摘要介绍了J2EE平台上JavaWeb开发的Spring框架的原理和特性,对其事务管理方面的应用进行了分析。
关键词Spring;J2EE;控制反转;事务处理引言在软件开发中出现过各种各样的框架,开源软件的兴起,使得各种各样的框架纷纷出现,例如,Apache组织下就拥有诸多的框架类产品。
框架就是一组协同工作的类,它们为特定类型的软件构筑了一个可重用的设计。
然而,传统的框架使得应用程序组件过分依赖于框架中的类,这种耦合度的提高降低了组件的复用性。
Spring框架的出现,使得组件之间更松散的耦合成为了可能。
Spring框架简介Spring框架是一个2003年2月才出现的开源项目,该开源项目起源自RodJohnson在2002年末出版的《ExpertOne-on-OneJ2EEDesignandDevelopment》一书中的基础性代码。
在该书中,RodJohnson倡导J2EE实用主义的设计思想,而Spring框架正是这一思想的更全面和具体的实现。
Spring框架由一个容器,一个配置和组织组件的框架,和一组内置的为事务、持久化和Web用户接口提供的服务组成。
作为一种轻量级的J2EE框架,Spring提供了一种有效的方式来建立和组织J2EE应用程序。
1、Spring特性IoC(InversionofControl;控制反转);又称DI(DependencyInjection;依赖注入);是面向对象领域新兴的编程思想;也是Spring的精髓所在。
简单地说;IoC就是指程序之间的关系由容器来控制;而不是传统实现中由程序代码直接操控。
这也就是所谓“控制反转”的概念所在:控制权由应用代码转到外部容器,控制权的转移,也就是所谓的"反转。
IoC将控制创建的职责搬进了框架中;并把它从应用代码脱离开来。
当使用Spring的IoC容器时只需指出组件需要的对象,在运行时Spring的IoC容器会根据XML配置数据提供给它。
spring事务管理面试题
spring事务管理面试题1、什么是事务管理?事务管理是指在数据库操作中,一系列相关的操作被作为一个整体来执行,要么全部执行成功,要么全部回滚到初始状态。
Spring事务管理是Spring框架中提供的用于管理数据一致性和完整性的机制。
2、Spring事务管理的特点有哪些?(1)原子性:事务作为一个整体,要么全部执行成功,要么全部回滚,不会出现部分执行的情况。
(2)一致性:事务执行过程中,数据的一致性得到保证,在操作过程中不会出现脏读、不可重复读、幻读等问题。
(3)隔离性:多个事务之间是相互隔离的,事务之间的操作不会相互干扰。
(4)持久性:事务一旦提交,对数据的修改是永久性的,即使系统发生故障也能够保证数据的一致性。
3、Spring框架中提供了哪些方式来实现事务管理?Spring框架中提供了两种方式来实现事务管理:(1)基于编程的事务管理:通过编写代码来实现事务的提交、回滚等操作。
可以使用TransactionTemplate类或者实现PlatformTransactionManager接口来实现编程式事务管理。
(2)基于声明式的事务管理:通过配置XML或注解的方式来实现事务的管理,不需要编写繁琐的代码。
可以使用<tx:advice>和<tx:attributes>等标签来实现声明式事务管理。
4、请简要介绍Spring声明式事务的实现原理。
Spring声明式事务的实现原理是通过AOP(面向切面编程)思想来完成的。
在编译期或运行期,Spring会通过动态代理技术为每个被@Transactional注解或XML配置的方法生成一个代理对象。
该代理对象在执行方法前后会根据事务的配置进行事务的提交、回滚等操作。
5、Spring事务的传播行为有哪几种?Spring事务的传播行为主要包括以下几种:(1)REQUIRED:支持当前事务,如果当前没有事务,则新建一个事务。
(2)SUPPORTS:支持当前事务,如果当前没有事务,则以非事务方式执行。
spring事务管理面试题
spring事务管理面试题Spring框架是一个Java平台上的开源框架,它主要提供了一种非常简便的方式来开发企业级Java应用程序。
Spring框架的核心特性之一是事务管理。
在面试中,可能会涉及到与Spring事务管理相关的问题。
本文将为你提供一些常见的Spring事务管理面试题以及对应的答案。
一、什么是Spring的事务管理?Spring事务管理是指通过Spring框架提供的一些特性和API,对应用程序中的数据库事务进行管理和控制。
Spring框架为我们提供了多种事务管理策略,包括基于注解的声明式事务管理和编程式事务管理。
二、Spring事务管理的优点是什么?1. 简化事务管理:Spring框架通过提供一致的异常处理和统一的事务管理API,大大简化了事务管理的复杂性。
2. 提高代码可读性和可维护性:通过使用Spring的声明式事务管理,我们可以将事务相关的代码与业务逻辑代码分离,提高代码结构的清晰度,同时也方便后续的维护和扩展。
3. 支持多种事务管理策略:Spring框架支持各种各样的事务管理策略,包括本地事务、分布式事务等,可以根据具体需求选择最合适的策略。
4. 与其他框架的无缝集成:由于Spring框架的广泛应用,它可以与其他流行的框架(如Hibernate、MyBatis等)进行无缝集成,提供完整的应用解决方案。
三、Spring事务管理的实现方式有哪些?1. 基于注解的声明式事务管理:通过在方法或类级别上添加事务相关的注解,来声明事务的边界和行为。
2. 编程式事务管理:通过在代码中显式地使用Spring提供的事务管理API来管理事务的开始、提交或回滚。
3. XML配置方式:通过在Spring的配置文件中定义事务管理器和事务切面,来管理事务。
四、如何配置基于注解的声明式事务管理?基于注解的声明式事务管理配置一般需要以下步骤:1. 在Spring的配置文件中启用事务注解驱动:```xml<tx:annotation-driven/>```2. 配置事务管理器:```xml<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManage r"><property name="dataSource" ref="dataSource"/></bean>```3. 在需要事务管理的类或方法上添加@Transactional注解:```java@Transactionalpublic void doSomething() {// 业务逻辑代码}```五、什么是事务传播行为?事务传播行为定义了当一个事务方法调用另一个事务方法时,被调用的方法的事务如何进行管理。
Spring事务的一些基本知识(三)--事务不生效,事务不回滚
Spring事务的⼀些基本知识(三)--事务不⽣效,事务不回滚⼀、事务不⽣效1.访问权限问题众所周知,java 的访问权限主要有四种:private、default、protected、public,它们的权限从左到右,依次变⼤。
但如果我们在开发过程中,把某些事务⽅法,定义了错误的访问权限,就会导致事务功能出问题。
⽅法的访问权限被定义成了private,这样会导致事务失效,spring 要求被代理⽅法必须是public的。
也就是说,如果我们⾃定义的事务⽅法(即⽬标⽅法),它的访问权限不是public,⽽是 private、default 或 protected 的话,spring 则不会提供事务功能。
2. ⽅法⽤ final 修饰有时候,某个⽅法不想被⼦类重写,这时可以将该⽅法定义成 final 的。
普通⽅法这样定义是没问题的,但如果将事务⽅法定义成 final,会导致事务失效。
如果你看过 spring 事务的源码,可能会知道 spring 事务底层使⽤了 aop,也就是通过 jdk 动态代理或者 cglib,帮我们⽣成了代理类,在代理类中实现的事务功能。
但如果某个⽅法⽤ final 修饰了,那么在它的代理类中,就⽆法重写该⽅法,⽽添加事务功能。
注意:如果某个⽅法是 static 的,同样⽆法通过动态代理,变成事务⽅法。
3.⽅法内部调⽤有时候我们需要在某个 Service 类的某个⽅法(⽆事务)中,调⽤另外⼀个事务⽅法。
那么问题来了,如果有些场景,确实想在同⼀个类的某个⽆事务⽅法中,调⽤它⾃⼰的另外⼀个⽅法,该怎么办呢?3.1 新加⼀个 Service ⽅法这个⽅法⾮常简单,只需要新加⼀个 Service ⽅法,把 @Transactional 注解加到新 Service ⽅法上,把需要事务执⾏的代码移到新⽅法中。
具体代码如下:3.2 在该 Service 类中注⼊⾃⼰如果不想再新加⼀个 Service 类,在该 Service 类中注⼊⾃⼰也是⼀种选择。
【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不一样
【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不⼀样3.2章中按照书中的步骤写好相应类的映射关系,发现启动时,之前在3.1章中建的表全部被删重新建⽴了,并且Ingredient表的数据没了,由于使⽤了JPA,默认使⽤的是hibernate,在启动时会删除所有的表并重新的建⽴表结构,⽽且schema.sql和data.sql中的语句并没有执⾏。
解决办法很简单,在application.properties⽂件中加⼊下⾯的配置:spring.jpa.hibernate.ddl-auto=none关闭掉hibernate的ddl的处理功能就能⾏了。
不过还有⼀些地⽅需要调整,在3.1章的表字段的命名是java风格的,在执⾏hibernate的查询语句时会报错,就拿Taco来说:package tacos;import java.util.Date;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.PrePersist;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;import lombok.Data;@Data@Entitypublic class Taco {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;private Date createdAt;@NotNull@Size(min=5, message="Name must be at least 5 characters long")private String name;@ManyToMany(targetEntity=Ingredient.class)@Size(min=1, message="You must choose at least 1 ingredient")private List<Ingredient> ingredients;@PrePersistvoid createdAt() {this.createdAt = new Date();}}由于createdAt属性未加上@Column注解,那么你会认为它对应的字段会是createdAt,实际上再查询时,你会发现他映射的字段是created_at,即使你给他加上@Column(name="createdAt")也不起作⽤,但是你给他加上@Column(name="createdat")确实可以的。
Spring源码剖析9:Spring事务源码剖析
Spring源码剖析9:Spring事务源码剖析本系列⽂章将整理到我在GitHub上的《Java⾯试指南》仓库,更多精彩内容请到我的仓库⾥查看喜欢的话⿇烦点下Star哈⽂章将同步到我的个⼈博客:本⽂是微信公众号【Java技术江湖】的《Spring和SpringMVC源码分析》其中⼀篇,本⽂部分内容来源于⽹络,为了把本⽂主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引⽤其中了⼀些⽐较好的博客⽂章,如有侵权,请联系作者。
该系列博⽂会告诉你如何从spring基础⼊⼿,⼀步步地学习spring基础和springmvc的框架知识,并上⼿进⾏项⽬实战,spring框架是每⼀个Java⼯程师必须要学习和理解的知识点,进⼀步来说,你还需要掌握spring甚⾄是springmvc的源码以及实现原理,才能更完整地了解整个spring技术体系,形成⾃⼰的知识框架。
后续还会有springboot和springcloud的技术专题,陆续为⼤家带来,敬请期待。
为了更好地总结和检验你的学习成果,本系列⽂章也会提供部分知识点对应的⾯试题以及参考答案。
如果对本系列⽂章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博⽂的创作和修订。
声明式事务使⽤Spring事务是我们⽇常⼯作中经常使⽤的⼀项技术,Spring提供了编程、注解、aop切⾯三种⽅式供我们使⽤Spring事务,其中编程式事务因为对代码⼊侵较⼤所以不被推荐使⽤,注解和aop切⾯的⽅式可以基于需求⾃⾏选择,我们以注解的⽅式为例来分析Spring事务的原理和源码实现。
⾸先我们简单看⼀下Spring事务的使⽤⽅式,配置:<tx:annotation-driven transaction-manager="transactionManager"/><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>在需要开启事务的⽅法上加上@Transactional注解即可,这⾥需要注意的是,当标签在不指定transaction-manager属性的时候,会默认寻找id固定名为transactionManager的bean作为事务管理器,如果没有id为transactionManager的bean并且在使⽤@Transactional注解时也没有指定value(事务管理器),程序就会报错。
hibernate和spring框架技术难点及其要点总结
个人总结希望能给你带来一些帮助,限于时间篇幅只能如此,如有不方便之处,望见谅.出处个人博客: /bloghibernate二级缓存二级缓存也称为进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享阅读全文>>标签:缓存hibernate hibernate配置2012-6-20 15:50:00 点击:19 评论:0hibernate与jdbc应用对比一、Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架,和App Server,和EJB没有什么必然的联系。
Hibernate可以用在任何JDBC可以使用的场合,例如Java应用程序的数据库访问代码,DAO接口的实现类,甚至可以是BMP里面的访问数据库的... 阅读全文>>标签:hibernate jdbc2012-5-21 13:57:00 点击:0 评论:0HibernateDaoSupport与JdbcDaoSupportDao 的支持类可以有好多,如: JdbcDaoSupport , HibernateDaoSupport ,JdoDaoSupport等,下面对最常用的HibernateDaoSupport与JdbcDaoSupport做一小总结:一、在Spring框架中实现连接数... 阅读全文>>2012-5-21 13:53:00 点击:1 评论:0Hibernate的几种查询方式-HQL,QBC,QBE,离线查询,复合查询,分页查询...HQL查询方式这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多。
条件查询、分页查询、连接查询、嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象。
其它的,包括一些查询函数(count(),sum()等)、... 阅读全文>>标签:hibernate2012-5-21 13:51:00 点击:1 评论:0hibernate的createSQLQuery的几种用法用法一:对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。
Spring中声明式事务存在的优缺点以及注意事项!
Spring中声明式事务存在的优缺点以及注意事项!事务管理在系统开发中是不可缺少的⼀部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。
关于事务的基础知识,如什么是事务,数据库事务以及Spring事务的ACID、隔离级别、传播机制、⾏为等,就不在这篇⽂章中详细介绍了。
默认⼤家都有⼀定的了解。
本⽂,作者会先简单介绍下什么是声明式事务和编程式事务,再说⼀下为什么我不建议使⽤声明式事务。
编程式事务基于底层的API,如PlatformTransactionManager、TransactionDefinition和TransactionTemplate等核⼼接⼝,开发者完全可以通过编程的⽅式来进⾏事务管理。
编程式事务⽅式需要是开发者在代码中⼿动的管理事务的开启、提交、回滚等操作。
public void test() {TransactionDefinition def = new DefaultTransactionDefinition();TransactionStatus status = transactionManager.getTransaction(def);try {// 事务操作// 事务提交mit(status);} catch (DataAccessException e) {// 事务提交transactionManager.rollback(status);throw e;}} 如以上代码,开发者可以通过API⾃⼰控制事务。
声明式事务声明式事务管理⽅法允许开发者配置的帮助下来管理事务,⽽不需要依赖底层API进⾏硬编码。
开发者可以只使⽤注解或基于配置的 XML 来管理事务。
@Transactionalpublic void test() {// 事务操作}如上,使⽤@Transactional即可给test⽅法增加事务控制。
当然,上⾯的代码只是简化后的,想要使⽤事务还需要⼀些配置内容。
SpringAOP应用场景之事务管理
SpringAOP应⽤场景之事务管理1、事务执⾏的时候是在前⾯开启事务,后⾯关闭事务,结束事务有两种⽅式,⼀种是正常的提交事务,⼀种是出现问题回滚事务。
spring事务默认只有在抛出unchecked Exception才会回滚UncheckedException包括error和runtimeException派⽣出的所有⼦类2、什么时候才⽤事务?对数据库的数据进⾏批量或连表操作时,为了保证数据的⼀致性和正确性,我们需要添加事务管理机制进⾏管理。
当对数据库的数据进⾏操作失败时,事务管理可以很好保证所有的数据回滚到原来的数据,如果操作成功,则保证所有需要更新的数据持久化。
例如:1.转账:A对B转账,需要先把A的钱减掉再把B的钱加上,这两个操作任何⼀个失败,都要撤销整个转账过程,不然会出⼤问题。
2.向数据库中插⼊订单时,先插⼊订单再插⼊订单项,这两个操作任何⼀个失败都会影响数据的⼀致性,所以必须做事务的处理3、Spring事务的配置声明式事务(不需要开启注解代理等等)配置通知(说明哪些⽅法需要拦截,被拦截的⽅法将应⽤配置好的事务属性)配置切⼊点需要对哪个类进⾏事务管理注意:只会管理通知中有的那些⽅法⼀. Spring⽀持编程式事务管理和声明式事务管理两种⽅式 编程式事务管理使⽤TransactionTemplate或者直接使⽤底层的PlatformTransactionManager。
对于编程式事务管理,spring推荐使⽤TransactionTemplate。
声明式事务管理建⽴在AOP之上的。
其本质是对⽅法前后进⾏拦截,然后在⽬标⽅法开始之前创建或者加⼊⼀个事务,在执⾏完⽬标⽅法之后根据执⾏情况提交或者回滚事务。
声明式事务最⼤的优点就是不需要通过编程的⽅式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置⽂件中做相关的事务规则声明(或通过基于@Transactional注解的⽅式),便可以将事务规则应⽤到业务逻辑中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JdbcUserService 通过 Spring AOP 事务增强的配置,让所有 public 方法都工作在 事务环境中。也即让 logon()和 updateLastLogonTime()方法拥有事务功能。在 logon() 方法内部,我们在①处通过调用 jdbcTemplate.getDataSource().getConnection()显式获取 一个连接,这个连接不是 logon()方法事务上下文线程绑定的连接,所以如果开发者 如果没有手工释放这连接(显式调用 Connection#close()方法),则这个连接将永久 被占用(处于 active 状态),造成连接泄漏!下面,我们编写模拟运行的代码,查 看方法执行对数据连接的实际占用情况:
Company: 无需填写 Photo filename: images/chenxh.jpg
Abstract: Spring 的事务管理是被使用最多的功能之一,虽然 Spring 事务管理已经将要做
的事情减到最小。但是在实际开发中,如果使用不当,依然会造成数据连接泄漏问题。本系 列以实际应用中所碰到的各种复杂的场景为着眼点,对这些应用的难点进行深度的剖析。
概述
对于应用开发者来说,数据连接泄漏无疑是一个可怕的梦魇。只要你开发的应 用存在数据连接泄漏的问题,应用程序最终都将因数据连接资源的耗尽而崩溃,甚 至还可能引起数据库的崩溃。数据连接泄漏像一个黑洞那样让开发者避之唯恐不 及。
Spring DAO 对所有支持的数据访问技术框架都使用模板化技术进行了薄层的封 装。只要你的程序都使用 Spring DAO 的模板(如 JdbcTemplate,HibernateTemplate 等)进行数据访问,一定不会存在数据连接泄漏的问题――这是 Spring 给予我们的 郑重的承诺!如果使用 Spring DAO 模板进行数据操作,我们无需关注数据连接 (Connection)及其衍生品(Hibernate 的 Session 等)的获取和释放的操作,模板类 已经通过其内部流程替我们完成了,且对开发者是透明的。
}
在 JdbcUserService 中添加一个可异步执行 logon()方法的 asynchrLogon()方法, 我们通过异步执行 logon()以及让主线程睡眠的方式模拟多线程环境下的执行场景。 在不同的执行点,通过 reportConn()方法汇报数据源连接的占用情况。
使用如下的 Spring 配置文件对 JdbcUserServie 的方法进行事务增强:
的JAVA开发,设计,架构的经验。技术研发之余,常将经验所得行诸于文字,作者是国内多 个著名技术网站的专栏作者,在各大技术网站、报刊杂志发表过数十篇技术文章,广受读者 好评。于 2005 年出版《精通 JBuilder 2005》,于2007年出版《精通 Spring 2.x--企业 应用开发详解》。
public UserServiceRunner(JdbcUserService userService, String userName) { erService = userService; erName = userName;
} public void run() {
@Service("jdbcUserService") public class JdbcUserService {
@Autowired private JdbcTemplate jdbcTemplate;
public void logon(String userName) { try { //①直接从数据源获取连接,后续程序没有显式释放该连接 Connection conn = jdbcTemplate.getDataSource().getConnection(); String sql = "UPDATE t_user SET last_logon_time=? WHERE user_name =?"; jdbcTemplate.update(sql, System.currentTimeMillis(), userName); Thread.sleep(1000);//②模拟程序代码的执行时间 } catch (Exception e) { e.printStackTrace(); }
UserServiceRunner runner = new UserServiceRunner(userService, userName); runner.start(); } private static class UserServiceRunner extends Thread { private JdbcUserService userService; private String userName;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.sql.Connection;
清单3.applicationContext.xml
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance" xmlns:context="/schema/context" xmlns:p="/schema/p" xmlns:aop="/schema/aop" xmlns:tx="/schema/tx" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-3.0.xsd /schema/context /schema/context/spring-context-3.0.xsd /schema/aop /schema/aop/spring-aop-3.0.xsd /schema/tx /schema/tx/springtx-3.0.xsd"> <context:component-scan base-package="user.connleak"/> <bean id="dataSource"
那么,如何获取这些被 Spring 管控的数据连接呢?Spring 提供了两种方法:其 一 是 使 用 数 据 资 源 获 取 工 具 类 , 其 二 是 对 数 据 源 ( 或 其 衍 生 品 如 Hibernate SessionFactory)进行代理。在具体介绍这些方法之前,让我们先来看一下各种引发 数据连接泄漏的场景。
BasicDataSource basicDataSource = (BasicDataSource) ctx.getBean("dataSource"); //④汇报数据源初始连接占用情况 JdbcUserService.reportConn(basicDataSource);
JdbcUserService.asynchrLogon(userService, "tom"); JdbcUserService.sleep(500); //⑤此时线程 A 正在执行 JdbcUserService#logon()方法 JdbcUserService.reportConn(basicDataSource);
import mons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
userService.logon(userName); } } //② 让主执行线程睡眠一段指定的时间 public static void sleep(long time) { try {
Thread.sleep(time); } catch (InterruptedExcepFra bibliotekion e) {
JdbcUserService.sleep(2000); //⑥此时线程 A 所执行的 JdbcUserService#logon()方法已经执行完毕 JdbcUserService.reportConn(basicDataSource);
JdbcUserService.asynchrLogon(userService, "john"); JdbcUserService.sleep(500);
用于 developerWorks 文章的 Microsoft Word 模板
Date: February 20, 2010 Type of Submission: Article
Title: Spring事务管理高级应用难点剖析(3) Subtitle:
Keywords: Spring, 事务管理,高级应用,连接泄漏
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("user/connleak/applicatonContext.xml"); JdbcUserService userService = (JdbcUserService) ctx.getBean("jdbcUserService");