Spring事务编写
2015-09-27 21:27
363 查看
提到事务大家可能都比较熟悉了,日常项目中也会经常的用到。在Spring相关的应用中,调用Spring集成的接口,就可以完成事务程序的编写。虽然编写过一些事务应用,但对Spring事务的结构,JDBC以及数据库层面的支撑有些生疏,抽时间整理了一下。
持久层支持
业务事务的实现最终还是需要依赖数据库对事务的支撑。事务具有四大特性:原子性、一致性、隔离性、持久性(ACID)。原子性、一致性、持久性在各数据库中定义和支持差别不大。针对隔离性,不同数据库产品对其支持不同。
事务隔离级别
标准的SQL定义四种事务隔离级别,以及每种隔离级别导致的问题如下:
未提交读 - ReadUncommitted - 脏读
提交读 - Read Committed - 不可重复读
重复读 - Repeatable Read - 幻想读
序列化 - Serializable
各大数据库对这些事务的支持各不相同:
SQL SERVER以上四种全部支持。
Oracle数据库不支持ReadUncommitted和Repeatable Read。Oracle的默认隔离级别是Read Committed, 不完全满足隔离性的要求。
MySql InnoDB引擎以上四种全部支持,默认支持的隔离级别是Repeatable Read。但是,InnoDB 在保证Repeatable Read的前提下,用Next-key locking算法(相对谓词锁,锁定的是范围而不是条件),同时避免了幻想读。因此,InnoDB默认的隔离级别能够完全保证事务的隔离性要求。
事务分类
事务主要分为以下几类:扁平事务、带有保存点的扁平事务、链事务、嵌套事务、分布式事务
扁平事务:实际使用中最常见的事务,由begin/rollback/commit等组成。其间的操作作为原子操作,要么全部执行,要么全部回滚。
带有保存点的扁平事务:可以在事务执行的过程中设定标志位,在需要回滚时,可以指定相应的标志位进行部分回滚。
链事务:可以看做一个有约束的带有保存点的扁平事务,它不能随意的回滚到某个点,只能回滚到最近的保存点。
嵌套事务:在事务中嵌入事务,外部的称为父事务,内部的称为子事务。子事务的提交并不能立即生效,只有等最外层的父事务提交之后才能生效。父事务的回滚会同样会导致子事务的回滚。
分布式事务:是指在分布式环境下的扁平事务。使用分布式事务InnoDB引擎的隔离级别必须设定为Serializable。
SQL代码块
start transaction; commit和rollback
JDBC驱动接口
JDBC中提供了相应的接口供相关事务的操作,这些接口定义在java.sql.Connection中:
首先,如果想主动控制事务的提交,必须把自动提交设定为false.
connection.setAutoCommit(false);
在将auto commit设定成false,在事务提交或者回滚之前会锁定相应的数据,因此需要及时提交或者回滚,尤其是在发生异常事。否则可能因为未处理异常导致数据长时间锁定,发生死锁。
需要进行带有保存点的事务时,设定保存点:
Savepoint setSavepoint(),
Savepoint setSavepoint(String name),
同样释放保存点:
releaseSavepoint(Savepointsavepoint)
当需要回滚或者回滚到某个保存点时:
rollback() //回滚整个事务
rollback(Savepointsavepoint) //回滚到特定保存点
正确执行后提交:
commit()
设定事务隔离级别:
setTransactionIsolation(intlevel)。
事务隔离级别就是在前面提及到Read Uncommitted,Read Committed,Repeatable Read,Serializable。具体要根据底层数据库的支持来设定值。例如Oracle就不支持Read Uncommitted,Repeatable Read。
Spring事务处理
Spring事务处理模块在org.springframework.transaction包中。
有三个重要的接口。PlatformTransactionManager、TransactionDefinition、TransactionStatus
PlatformTransactionManager
PlatformTransactionManager是事务管理器的基础,不管是声明式的还是编程式的事务管理都需要此抽象来完成。常见的事务管理器根据数据源DataSource的不同有以下几种常见管理器:
DataSourceTransactionManager:适用于直接通过JDBC驱动连接的数据源。
HibernateTransactionManager:适用于通过Hibernate持久层框架连接的数据源。DataSource为Hibernate SessionFactory。
JpaTransactionManager:JPA是JavaPersistence API,通过注解的形式进行实体持久化标记,结合Hibernate等ORM框架一起使用。从JDK.50开始支持。Spring 引入JpaTransactionManager来支持JPA。DataSource为EntityManager.
TransactionDefinition
TransactionDefinition接口,定义了事务的隔离级别和传播行为,超时时间。
Spring事务传播行为:
PROPAGATION_REQUIRED:
必须有一个事务:如果当前存在事务、则使用当前事务,否则创建新的事务。
PROPAGATION_SUPPORTS
事务可有可无:如果当前存在事务,则使用当前事务,否则不在事务中执行
PROPAGATION_MANDATORY
必须在当前事务执行,否则报错
PROPAGATION_REQUIRES_NEW
不管当前有无事务,均创建一个新的事务执行
PROPAGATION_NOT_SUPPORTED
不在事务中运行,开启新的连接,不使用事务
PROPAGATION_NEVER
不在事务中执行,如果存在当前事务则抛出异常
PROPAGATION_NESTED
如果当前存在事务,则应运行于嵌套事务中。
Spring事务隔离级别:
Spring事务隔离级别定义,与标准SQL定义一致,但需要注意底层数据库的支持。
TransactionStatus
TransactionStatus代表了开启后的事务状态。包括是否是新事务,是否有保存点,是否完成或回滚,设定回滚标识等。
Spring编写事务应用
Spring提供了两种编写事务处理应用的方式:声明式和编程式。下面主要介绍下编程式事务编写:
使用TransactionTemplate来进行编写事务,TransactionTemplate继承了DefaultTransactionDefinition。
1、TransactionTemplate中需传入transactionManager,来进行事务操作:创建、提交、回滚。
2、execute方法来执行业务事务。该方法接收TransactionCallback接口作为参数。此处使用回调设计模式:即被调用方也可以调用对方接口。TransactionCallback通常作为匿名类来使用,只有一个方法doInTransaction,用于定义事务执行的主体。execute代码如下所示:
编程示例代码如下:
主要有以下几部分:DataSource、TransactionManager、TransactionTemplate、事务执行主体
持久层支持
业务事务的实现最终还是需要依赖数据库对事务的支撑。事务具有四大特性:原子性、一致性、隔离性、持久性(ACID)。原子性、一致性、持久性在各数据库中定义和支持差别不大。针对隔离性,不同数据库产品对其支持不同。
事务隔离级别
标准的SQL定义四种事务隔离级别,以及每种隔离级别导致的问题如下:
未提交读 - ReadUncommitted - 脏读
提交读 - Read Committed - 不可重复读
重复读 - Repeatable Read - 幻想读
序列化 - Serializable
各大数据库对这些事务的支持各不相同:
SQL SERVER以上四种全部支持。
Oracle数据库不支持ReadUncommitted和Repeatable Read。Oracle的默认隔离级别是Read Committed, 不完全满足隔离性的要求。
MySql InnoDB引擎以上四种全部支持,默认支持的隔离级别是Repeatable Read。但是,InnoDB 在保证Repeatable Read的前提下,用Next-key locking算法(相对谓词锁,锁定的是范围而不是条件),同时避免了幻想读。因此,InnoDB默认的隔离级别能够完全保证事务的隔离性要求。
事务分类
事务主要分为以下几类:扁平事务、带有保存点的扁平事务、链事务、嵌套事务、分布式事务
扁平事务:实际使用中最常见的事务,由begin/rollback/commit等组成。其间的操作作为原子操作,要么全部执行,要么全部回滚。
带有保存点的扁平事务:可以在事务执行的过程中设定标志位,在需要回滚时,可以指定相应的标志位进行部分回滚。
链事务:可以看做一个有约束的带有保存点的扁平事务,它不能随意的回滚到某个点,只能回滚到最近的保存点。
嵌套事务:在事务中嵌入事务,外部的称为父事务,内部的称为子事务。子事务的提交并不能立即生效,只有等最外层的父事务提交之后才能生效。父事务的回滚会同样会导致子事务的回滚。
分布式事务:是指在分布式环境下的扁平事务。使用分布式事务InnoDB引擎的隔离级别必须设定为Serializable。
SQL代码块
start transaction; commit和rollback
JDBC驱动接口
JDBC中提供了相应的接口供相关事务的操作,这些接口定义在java.sql.Connection中:
首先,如果想主动控制事务的提交,必须把自动提交设定为false.
connection.setAutoCommit(false);
在将auto commit设定成false,在事务提交或者回滚之前会锁定相应的数据,因此需要及时提交或者回滚,尤其是在发生异常事。否则可能因为未处理异常导致数据长时间锁定,发生死锁。
需要进行带有保存点的事务时,设定保存点:
Savepoint setSavepoint(),
Savepoint setSavepoint(String name),
同样释放保存点:
releaseSavepoint(Savepointsavepoint)
当需要回滚或者回滚到某个保存点时:
rollback() //回滚整个事务
rollback(Savepointsavepoint) //回滚到特定保存点
正确执行后提交:
commit()
设定事务隔离级别:
setTransactionIsolation(intlevel)。
事务隔离级别就是在前面提及到Read Uncommitted,Read Committed,Repeatable Read,Serializable。具体要根据底层数据库的支持来设定值。例如Oracle就不支持Read Uncommitted,Repeatable Read。
Spring事务处理
Spring事务处理模块在org.springframework.transaction包中。
有三个重要的接口。PlatformTransactionManager、TransactionDefinition、TransactionStatus
PlatformTransactionManager
PlatformTransactionManager是事务管理器的基础,不管是声明式的还是编程式的事务管理都需要此抽象来完成。常见的事务管理器根据数据源DataSource的不同有以下几种常见管理器:
DataSourceTransactionManager:适用于直接通过JDBC驱动连接的数据源。
HibernateTransactionManager:适用于通过Hibernate持久层框架连接的数据源。DataSource为Hibernate SessionFactory。
JpaTransactionManager:JPA是JavaPersistence API,通过注解的形式进行实体持久化标记,结合Hibernate等ORM框架一起使用。从JDK.50开始支持。Spring 引入JpaTransactionManager来支持JPA。DataSource为EntityManager.
TransactionDefinition
TransactionDefinition接口,定义了事务的隔离级别和传播行为,超时时间。
Spring事务传播行为:
PROPAGATION_REQUIRED:
必须有一个事务:如果当前存在事务、则使用当前事务,否则创建新的事务。
PROPAGATION_SUPPORTS
事务可有可无:如果当前存在事务,则使用当前事务,否则不在事务中执行
PROPAGATION_MANDATORY
必须在当前事务执行,否则报错
PROPAGATION_REQUIRES_NEW
不管当前有无事务,均创建一个新的事务执行
PROPAGATION_NOT_SUPPORTED
不在事务中运行,开启新的连接,不使用事务
PROPAGATION_NEVER
不在事务中执行,如果存在当前事务则抛出异常
PROPAGATION_NESTED
如果当前存在事务,则应运行于嵌套事务中。
Spring事务隔离级别:
Spring事务隔离级别定义,与标准SQL定义一致,但需要注意底层数据库的支持。
TransactionStatus
TransactionStatus代表了开启后的事务状态。包括是否是新事务,是否有保存点,是否完成或回滚,设定回滚标识等。
Spring编写事务应用
Spring提供了两种编写事务处理应用的方式:声明式和编程式。下面主要介绍下编程式事务编写:
使用TransactionTemplate来进行编写事务,TransactionTemplate继承了DefaultTransactionDefinition。
1、TransactionTemplate中需传入transactionManager,来进行事务操作:创建、提交、回滚。
2、execute方法来执行业务事务。该方法接收TransactionCallback接口作为参数。此处使用回调设计模式:即被调用方也可以调用对方接口。TransactionCallback通常作为匿名类来使用,只有一个方法doInTransaction,用于定义事务执行的主体。execute代码如下所示:
编程示例代码如下:
主要有以下几部分:DataSource、TransactionManager、TransactionTemplate、事务执行主体
<span style="white-space:pre"> </span>//定义事务管理器
<span style="white-space:pre"> </span><bean id="aaTransactionManager" <span style="white-space:pre"> </span>class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <span style="white-space:pre"> </span><ref local="**" /> </property> </bean>
//定义事务执行模板 <bean id="bbTransactionTemplate" <span style="white-space:pre"> </span>class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager"> <ref local="aaTransactionManager" /> </property> </bean> <span style="white-space:pre"> </span>//事务业务逻辑代码如下: <span style="white-space:pre"> </span>return bbTransactionTemplate.execute( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { *** try { **** } catch (Exception e) { status.setRollbackOnly(); log.error("**"); } return obj; } });
相关文章推荐
- 设计模式之单例模式(java)
- JAVAWEB学习
- java SE复习笔记50
- java SE复习笔记49
- java SE复习笔记48
- java SE复习笔记47
- java SE复习笔记46
- java SE复习笔记45
- java SE复习笔记44
- Eclipse-Mars Release (4.5.0)创建Maven项目报错
- java SE复习笔记43
- java SE复习笔记42
- java SE复习笔记41
- Java工具类(二) 模版导出工具类
- IO--java流对象
- Struts2 的Action中取得请求参数值的几种方法
- java 链接mysql 参考文章和遇到的问题
- eclipse常用设置
- JAVA 常用类
- Java工具类(一) 金额转换工具类