spring 事务初识

1.spring事务的主要接口,首先盗图一张,展示出spring 事务的相关接口.Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

2.事务基本属性的定义

  2.1 事务的属性

   事务的属性主要包括传播行为(propagation behavior),隔离级别(isolation level),超时时间,是否只读.这些属性在TransactionDefinition接口里面都有定义.

  2.2.1 传播行为 

   当事务方法被另一个事务方法调用时,必须指定事务是如何传播的.即当前事务是否延续到新的事物方法中.

   spring定义了七种传播行为:

   PROPAGATION_REQUIRED : 当前方法必须运行在事物中,若当前事务存在则运行在当前事务中,否则启动新事务

      PROPAGATION_SUPPORT :  当前方法不需要运行在事物中,但若是存在事务,该方法会在该事务中运行

PROPAGATION_MANDATORY : 当前方法必须运行在事物中,否则会抛出异常

   PROPAGATION_REQUIRED_NEW : 当前方法会启动一个新的事务,若当前上下文中已存在事务,则上下文中的事务会被挂起

   PROPAGATION_NOT_SUPPORTED : 当前方法不应该运行在事物当中,若上下文中存在事务,则改事务会被挂起

   PROPAGATION_NEVER : 当前方法不因运行在事物当中,若上下文中存在一个事物,则会抛出异常

   PROPAGATION_NESTED : 当前方法会单独的提交或回滚,不受上下文事务的影响.若上下文不存在事务,则同PROPAGATION_REQUIRED

   嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。

使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。

两个事务不是一个真正的嵌套事务。

使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。

PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 “内部” 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等.

当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行。

另一方面, PROPAGATION_NESTED 开始一个 “嵌套的” 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此                         savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务             的子事务, 如果外部事务 commit, 嵌套事务也会被 commit, 这个规则同样适用于 roll back.

   spring 默认传播行为为required 

 

  2.2.2 隔离级别 

   事务的5个隔离级别

   ISOLATION_DEFAULT : 使用数据库默认的隔离级别

   ISOLATION_READ_UNCOMMITTED : 允许读取尚未提交的事务,可能会出现,脏读,幻读,和不可重复读

   ISOLATION_READ_COMMITTED : 允许读取并发事务已经提交的事务,可以阻止脏读,但是扔可能出现幻读和不可重复读

   ISOLATION_REPEATEABLE_READ : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

   ISOLATION_SERIALIZABLE : 最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现

  2.2.3 是否只读

如果事务只对后端的数据库进行该操作,数据库可以利用事务的只读特性来进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为合适的优化措施。

  2.2.4 超时

   为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。事务超时就是事务的一个定时器,在特定时间内事               务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束

3. spring 声明式事务配置

  3.1 使用tx标签.

   

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="true">
<bean id="mysqlSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="routinDataSource" />
<property name="configLocation" value="classpath:/spring/mybatis.xml" />
<!-- 自动扫描entity目录, 省掉xml里的手工配置 -->
<property name="typeAliasesPackage" value="com.monkey.test.spring.transaction.entity" />
<!-- 显式指定Mapper文件位置 -->
<property name="mapperLocations">
<list>
<value>classpath*:/mybatis/**/**/*Mapper.xml</value>
</list>
</property>
</bean> <bean id="routinDataSource" class="com.monkey.test.spring.transaction.utils.datasource.SelfRutinDataSource">
<property name="targetDataSources">
<map>
<entry key="write" value-ref="mysqlDataSourceWrite"></entry>
<entry key="read" value-ref="mysqlDataSourceRead"></entry>
</map>
</property>
</bean> <!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="mysqlSqlSessionFactory" />
<property name="basePackage"
value="com.monkey.test.spring.transaction.repository" />
<!-- 优化速度 -->
<property name="annotationClass" value="com.monkey.test.spring.transaction.utils.JYBatis" />
</bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:/dbconfig.properties</value>
</list>
</property>
</bean> <!-- 配置数据源 -->
<bean name="mysqlDataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.mysql.driver}" />
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="${druid.initialSize}" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="${druid.maxActive}" />
<!-- 最大空闲连接数 -->
<!-- <property name="maxIdle" value="${druid.maxIdle}" /> -->
<!-- 最小空闲连接数 -->
<property name="minIdle" value="${druid.minIdle}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${druid.maxWait}" />
<!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="${druid.removeAbandoned}" />
<!-- 超过时间限制多长; -->
<property name="removeAbandonedTimeout" value="${druid.removeAbandonedTimeout}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />
<!-- 用来检测连接是否有效的sql,要求是一个查询语句 -->
<property name="validationQuery" value="${druid.validationQuery}" />
<!-- 申请连接的时候检测 -->
<property name="testWhileIdle" value="${druid.testWhileIdle}" />
<!-- 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
<property name="testOnBorrow" value="${druid.testOnBorrow}" />
<!-- 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
<property name="testOnReturn" value="${druid.testOnReturn}" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${druid.maxPoolPreparedStatementPerConnectionSize}" />
<!--属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat 日志用的filter:log4j 防御SQL注入的filter:wall -->
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="log4j2Filter" />
</list>
</property>
</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="mysqlDataSourceWrite"></property>
</bean>
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception" timeout="-1"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.monkey.test.spring.transaction.service.*.*(..))"/>
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
</aop:config> </beans>

  3.2 使用@Transaction注解

   

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="true">
<bean id="mysqlSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="routinDataSource" />
<property name="configLocation" value="classpath:/spring/mybatis.xml" />
<!-- 自动扫描entity目录, 省掉xml里的手工配置 -->
<property name="typeAliasesPackage" value="com.monkey.test.spring.transaction.entity" />
<!-- 显式指定Mapper文件位置 -->
<property name="mapperLocations">
<list>
<value>classpath*:/mybatis/**/**/*Mapper.xml</value>
</list>
</property>
</bean> <bean id="routinDataSource" class="com.monkey.test.spring.transaction.utils.datasource.SelfRutinDataSource">
<property name="targetDataSources">
<map>
<entry key="write" value-ref="mysqlDataSourceWrite"></entry>
<entry key="read" value-ref="mysqlDataSourceRead"></entry>
</map>
</property>
</bean> <!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="mysqlSqlSessionFactory" />
<property name="basePackage"
value="com.monkey.test.spring.transaction.repository" />
<!-- 优化速度 -->
<property name="annotationClass" value="com.monkey.test.spring.transaction.utils.JYBatis" />
</bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:/dbconfig.properties</value>
</list>
</property>
</bean> <!-- 配置数据源 -->
<bean name="mysqlDataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.mysql.driver}" />
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="${druid.initialSize}" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="${druid.maxActive}" />
<!-- 最大空闲连接数 -->
<!-- <property name="maxIdle" value="${druid.maxIdle}" /> -->
<!-- 最小空闲连接数 -->
<property name="minIdle" value="${druid.minIdle}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${druid.maxWait}" />
<!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="${druid.removeAbandoned}" />
<!-- 超过时间限制多长; -->
<property name="removeAbandonedTimeout" value="${druid.removeAbandonedTimeout}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />
<!-- 用来检测连接是否有效的sql,要求是一个查询语句 -->
<property name="validationQuery" value="${druid.validationQuery}" />
<!-- 申请连接的时候检测 -->
<property name="testWhileIdle" value="${druid.testWhileIdle}" />
<!-- 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
<property name="testOnBorrow" value="${druid.testOnBorrow}" />
<!-- 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能 -->
<property name="testOnReturn" value="${druid.testOnReturn}" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${druid.maxPoolPreparedStatementPerConnectionSize}" />
<!--属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat 日志用的filter:log4j 防御SQL注入的filter:wall -->
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="log4j2Filter" />
</list>
</property>
</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="mysqlDataSourceWrite"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/> </beans>

  

 

spring transaction 初识的更多相关文章

  1. 疑惑的 java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L

    在MAVEN项目里面,在整合spring和mybatis在执行数据库操作的时候报出了: java.lang.AbstractMethodError: org.mybatis.spring.transa ...

  2. spring Transaction Propagation 事务传播

    spring Transaction中有一个很重要的属性:Propagation.主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系. 我晓得有点儿抽象,这也是为什么我想要写 ...

  3. Spring Transaction属性之Propagation

    spring Transaction中有一个很重要的属性:Propagation.主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系. 我晓得有点儿抽象,这也是为什么我想要写 ...

  4. spring Transaction Management --官方

    原文链接:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html 12.  ...

  5. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer; at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.jav

    在整合spring和mybatis在执行数据库操作的时候报出了: java.lang.AbstractMethodError: org.mybatis.spring.transaction.Sprin ...

  6. org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout() mybatis和spring-mybatis版本不匹配问题

    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()  ...

  7. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L

    mybatis与springboot集成的时候,报错:java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManag ...

  8. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout

    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L ...

  9. springboot成神之——spring boot,spring jdbc和spring transaction的使用

    本文介绍spring boot,spring jdbc和spring transaction的使用 项目结构 依赖 application model层 mapper层 dao层 exception层 ...

随机推荐

  1. 【255】◀▶IEW-Unit20

    Unit 20 Environment: Tourism I.定语从句及分词在雅思写作中的运用 定语从句: 1. 先行词 2. 关系词:关系代词.关系副词 3. 非限制性定语从句 4. 分词和定语从句 ...

  2. 【总结整理】JQuery小技巧

    var item=$("#content").find(".item");//效率最高 var item=$("#content .item" ...

  3. p2371&bzoj2118 墨墨的等式

    传送门(bzoj) 题目 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存 ...

  4. 主元素问题(Java)

    x称为一个长度为n的数组的a的主元素,如果这个数组里面等于x的元素的数目不少于n/2个. 例如,a={2,3,2,2,5,3,2,4,2},x=2就是这个主元素.给定包含n个元素的数组a,主元素问题就 ...

  5. Java 课上的语录

    Java 课上的语录 在用系统类库的类的时候啊,你是不是充分的理解这个系统类库的类.比如这个 ArrayList 你是不是知道它里面有这样那样这样那样的函数,能够帮你做各种各样的事情.很重要,你不知道 ...

  6. Mybatis学习笔记之一——牛刀小试

    1.Mybaits核心对象SqlSession的作用: (1)向SQL语句传入参数: (2)执行SQl语句: (3)获取执行SQL语句的结果: (4)事务的控制: 2.核心配置文件(Configrat ...

  7. hdu6070(分数规划/二分+线段树区间更新,区间最值)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 给出一个题目提交序列, 从中选出一个正确率最小的子串. 选中的子串中每个题目当且仅当最 ...

  8. 洛谷P1275 魔板

    P1275 魔板 题目描述 有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格.每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗).我们可以通过若干操作使魔板从一个状态改变为另一个状 ...

  9. MCP|XN|Decreased Antibiotic Susceptibility Driven by Global Remodeling of the Klebsiella pneumoniae Proteome(肺炎杆菌通过整体重构蛋白质组降低抗生素敏感性)

    文献名:Decreased Antibiotic Susceptibility Driven by Global Remodeling of the Klebsiella pneumoniae Pro ...

  10. Java基础笔记(十)—— 数组

    数组是具有相同类型的数据的集合,是一种引用数据类型,一般具有固定的长度,并且在内存中占据连续的空间. 数组声明:数据类型[ ] 数组名;             数据类型 数组名[ ]; 如:int[ ...