博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列教程——15Spring事务管理器
阅读量:3958 次
发布时间:2019-05-24

本文共 4901 字,大约阅读时间需要 16 分钟。

Spring系列教程——15Spring事务管理器

文章目录

一.事务概念与特性讲解

1.概念

事务是属于数据库操作的概念,一个事务可有多个数据库操作组成,它是一个操作单元,组成它的操作作为一个整体,要么同时执行成功,要么同时失败

2.特性(ACID)

1.原子性

即整体性,是指事务包含的所有操作要么全部成功,要么全部失败.

2.一致性

即数据一致,一个事务执行之前和执行之后都必须处于一致性状态,比如当在执行一个事务的时候,数据库系统发生了异常,这时事务执行了一般,导致只有执行了的那一部分操作才被写入数据库,而剩下的未被写入,这就是一个不一致的状态。

3.隔离性

也即并发性,一个事务的执行应该与其并发执行的其他事务互不干扰,互相隔离

4.持久性

也即永久性,一个事务一旦提交了,那么他对数据库的修改将是永久的

3.隔离级别

事务的隔离级别一共有四种,由低到高为Read uncommitted、Read committed、Repeatable read 、Serializable。但是会产生脏读不可重复复读虚读(幻读)的问题。具体的例子可以参见这篇文章。

二.事务管理器介绍

1.准备讲解

首先我们需要讲解下面的红框里面的PlatformTransactionManager,TransactionDefinition,TransactionStatus三个接口。

在这里插入图片描述
PlatformTransactionManager:平台事务管理器,spring要管理事务,必须使用事务管理器,进行事务配置时,必须配置事务管理器。
TransactionDefinition:事务详情(事务定义、事务属性),spring用于确定事务具体详情。例如:隔离级别、是否只读、超时时间等。进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。
在这里插入图片描述
红框里面的内容我们理解,上面的内容介绍如下(关于传播行为详细演示可以参见,在后面讲事务代理工厂也会涉及到):
在这里插入图片描述
TransactionStatus:事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。spring底层根据状态进行相应操作。
在这里插入图片描述
接下来我们来看一个案例更好的理解.
1.准备表数据:

CREATE TABLE account(  id INT PRIMARY KEY AUTO_INCREMENT,  username VARCHAR(50),  money INT);INSERT INTO account(username,money) VALUES('jack','10000');INSERT INTO account(username,money) VALUES('rose','10000');

在这里插入图片描述

2.dao层:
IAccountDao接口

package dao;@SuppressWarnings("all")public interface IAccountDao {
//进账 public void inner(String inner,Integer money); //扣钱 public void out(String outer,Integer money);}

AccountDaoImpl实现类

package dao;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override public void inner(String inner, Integer money) {
getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner); } @Override public void out(String outer, Integer money) {
getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer); }}

3.Service层

IAccountService接口

package service;@SuppressWarnings("all")public interface IAccountService {
public void transfer(String outter,String inner,Integer money);}

AccountServiceImpl实现类

package service;import dao.IAccountDao;public class AccountServiceImpl implements IAccountService {
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao; } private IAccountDao accountDao; @Override public void transfer(String outter, String inner, Integer money) {
accountDao.inner(inner,money); accountDao.out(outter,money); }}

4.配置文件

5.测试

ApplicationContext context = new  ClassPathXmlApplicationContext("beans.xml");IAccountService service = (IAccountService) context.getBean("accountService");service.transfer("jack","rose",1000);

在这里插入图片描述

接下来我们才正式开始事务管理的内容。

2.手动事务管理配置

这一部分我们将讲解Spring底层的事务管理的实现,但是我们对该部分只要了解就够了,因为后面都会通过Aop来实现。

spring底层使用 TransactionTemplate 事务模板进行操作。

1.service 需要获得 TransactionTemplate
2.spring 配置模板,并注入给service
3.模板需要注入事务管理器
4.配置事务管理器:DataSourceTransactionManager ,需要注入DataSource

接下来我们按照上面的步骤来做。

1.在AccountServiceImpl里面配置模板

private TransactionTemplate template;public void setTemplate(TransactionTemplate template) {
this.template = template;}@Overridepublic void transfer(String outter, String inner, Integer money) {
final String out = outter; final String in = inner; final Integer mon = money; template.execute(new TransactionCallbackWithoutResult() {
@Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
accountDao.inner(in,mon); int i = 10/0; accountDao.out(out,mon); } });

2.beans.xml修改为下面内容

3.测试

仍然使用上面的代码
在执行到int i=10/0;时出现异常,但是表数据由于回滚而未出现隔离性问题。
在这里插入图片描述
在这里插入图片描述

3.事务代理工厂配置

Spring提供管理事务的代理工厂bean :TransactionProxyFactoryBean,这里我们采用的是AOP半自动的方式来讲解使用方式。(前面讲过,忘记了可以参考)

这里我们不再需要TransactionTemplate了,将tranfer方法还原:

@Overridepublic void transfer(String outter, String inner, Integer money) {
accountDao.inner(inner,money); int i = 10/0; accountDao.out(outter,money);}

beans.xml配置的配置

注意上面这一段:

我们还没有对transactionAttributes(事务属性)进行配置,我们先测试一下看可否保证数据安全。

在这里插入图片描述
这说明我们是事务管理工厂配置好后没有起到作用,原因在于我们没有配置transactionAttributes来就行限定。配置这一段内容:

PROPAGATION_REQUIRED,ISOLATION_DEFAULT

接下来我们先将表数据修改回来。

在这里插入图片描述
测试发现此时发生异常后数据保持正常:
在这里插入图片描述
加入我们把配置改为:

PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly

再来测试看看报什么异常:

在这里插入图片描述
还有-Exception,+Exception没有演示,这里留给读者。(不过要注意不一定只可以写Exception,还可以类似这样+java.lang.ArithmeticException)
上面的方式不是我们推荐的事务管理的配置方式,我们更推荐Aop配置与注解的方式,请见下一篇。

转载地址:http://wxlzi.baihongyu.com/

你可能感兴趣的文章
ntfs分区iis故障的解决
查看>>
个人创业“六大死穴”
查看>>
最重要的 12个 J2EE 最佳实践
查看>>
通过Java Swing看透MVC设计模式
查看>>
Java 理论与实践: 关于异常的争论
查看>>
编写高效的线程安全类
查看>>
提高Java代码可重用性的三个措施
查看>>
编写跨平台Java程序注意事项
查看>>
富人和穷人的12个经典差异
查看>>
java 注意事项[教学]
查看>>
MetaWeblogAPI测试
查看>>
软件配置管理概念-1,介绍
查看>>
软件配置管理概念-2,用户角色
查看>>
软件配置管理概念-3,CM系统的概念
查看>>
JSP/Servlet应用程序优化八法
查看>>
人生必修的181条佛理
查看>>
The Most Widely Used Java Libraries
查看>>
简单在单机使用apache-james(开源邮件服务器)
查看>>
lsof 快速起步
查看>>
使用ScribeFire方便地发布blog
查看>>