码迷,mamicode.com
首页 > 编程语言 > 详细

Spring事务管理

时间:2017-08-23 13:30:57      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:std   事务管理器   右键   级别   rman   sql   --   getbean   bsp   

-------------------siwuxie095

   

   

   

   

   

   

   

   

Spring 事务管理

   

   

(一)事务的相关概念

   

   

1、什么是事务

   

事务是逻辑上的一组操作,构成这组操作的各个逻辑单元,

要么一起成功,要么一起失败

   

   

   

   

2、事务特性(简称 ACID

   

1原子性:强调事务的不可分割

   

2一致性:事务执行前后,数据的完整性保持一致

   

3隔离性:一个事务在执行的过程中,不应该受到其他事务的干扰

   

4持久性:事务一旦结束,数据就持久到数据库

   

   

   

   

3、如果不考虑隔离性引发安全性问题

   

1脏读

   

一个事务读到了另一个事务未提交的数据

   

   

2不可重复读

   

一个事务读到了另一个事务已经提交的 update 的数据,导致多次查询结果不一致

   

   

3幻读(也称 虚读

   

一个事务读到了另一个事务已经提交的 insert 的数据,导致多次查询结果不一致

   

   

   

   

4、解决读问题:设置事务隔离级别

   

1未提交读:脏读、不可重复读、幻读都有可能发生

   

2已提交读:避免脏读,但不可重复读和幻读有可能发生

   

3可重复读:避免脏读和不可重复读,但幻读有可能发生

   

4可串行化:避免以上所有读问题

   

   

   

   

   

   

   

(二)Spring 事务管理 API

   

   

1、Spring 事务管理有两种方式

   

1编程式事务管理:手动编写代码实现事务管理

   

   

2声明式事务管理:通过一段配置实现事务管理(建议)

   

1)基于 XML 的方式

   

2)基于注解的方式

   

   

   

   

2、Spring 事务管理 API 介绍

   

1)接口:PlatformTransactionManager(事务管理器)

   

Spring 为不同的持久层框架提供了 PlatformTransactionManager 接口的不同实现类

   

ORM 持久层框架

实现类

Spring JDBC

DataSourceTransactionManager

iBatis

DataSourceTransactionManager

MyBatis

DataSourceTransactionManager

Hibernate

HibernateTransactionManager

JPA

JpaTransactionManager

JDO

JdoTransactionManager

JTA

JtaTransactionManager

   

   

   

2)接口:TransactionDefinition(事务定义)

   

用来定义事务相关属性,给事务管理器使用

   

1)隔离级别

   

2)传播行为

   

3)超时信息

   

4)是否只读

   

   

   

3)接口:TransactionStatus(事务状态)

   

事务运行过程中,记录每个时间点的事务状态信息

   

   

   

事务管理器根据事务定义的信息进行事务的管理,在此过程中

会产生一些状态,将事务状态记录下来

   

   

   

   

   

   

   

(三)测试:以转账为例

   

   

1、在 MySQL 中手动创建数据库和表

   

数据库名:tx_db,表名:account,字段:id、name、money

   

技术分享

   

   

手动添加数据,用作测试

   

技术分享

   

   

   

   

2、具体实现

   

1)编写一个 Dao 类

   

AccountDao.java:

   

package com.siwuxie095.dao;

   

import org.springframework.jdbc.core.JdbcTemplate;

   

public class AccountDao {

   

private JdbcTemplate jdbcTemplate;

 

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this.jdbcTemplate = jdbcTemplate;

}

 

public void lessMoney(String from, int money) {

String sql="update account set money=money-? where name=?";

jdbcTemplate.update(sql, money, from);

}

 

public void moreMoney(String to, int money) {

String sql="update account set money=money+? where name=?";

jdbcTemplate.update(sql, money, to);

}

 

}

   

   

   

2)编写一个 Service 类

   

AccountService.java:

   

package com.siwuxie095.service;

   

import com.siwuxie095.dao.AccountDao;

   

public class AccountService {

   

private AccountDao accountDao;

 

public void setAccountDao(AccountDao accountDao) {

this.accountDao = accountDao;

}

 

public void transfer(String from,String to,int money) {

accountDao.lessMoney(from, money);

accountDao.moreMoney(to, money);

}

 

}

   

   

   

3)在配置文件中进行配置

   

applicationContext.xml:

   

<?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:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx.xsd">

 

 

<!-- 配置内置连接池 -->

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<!--

jdbc:mysql:///tx_db jdbc:mysql://localhost:3306/tx_db 的简写

-->

<property name="url" value="jdbc:mysql:///tx_db"/>

<property name="username" value="root"/>

<property name="password" value="8888"/>

</bean>

 

 

<!-- 配置对象并注入属性 -->

<bean id="accountService" class="com.siwuxie095.service.AccountService">

<property name="accountDao" ref="accountDao"></property>

</bean>

 

<bean id="accountDao" class="com.siwuxie095.dao.AccountDao">

<property name="jdbcTemplate" ref="jdbcTemplate"></property>

</bean>

 

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

<!-- JdbcTemplate 源代码中有属性 dataSource 和其 set 方法,所以可以注入 -->

<property name="dataSource" ref="dataSource"></property>

</bean>

   

   

</beans>

   

   

   

4)编写一个测试类

   

TestDemo.java:

   

package com.siwuxie095.test;

   

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

   

import com.siwuxie095.service.AccountService;

   

public class TestDmo {

   

/**

* 手动加上 @Test 以进行单元测试(将自动导入 JUnit 4 jar 包)

*

* 选中方法名,右键->Run As->JUint Test

*/

@Test

public void testService() {

 

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

 

AccountService accountService=(AccountService) context.getBean("accountService");

 

accountService.transfer("小白", "小黑", 1000);

}

 

}

   

   

   

   

3、问题所在

   

上面的程序虽然可以正常运行,并实现转账功能,但如果在一个人

转出钱时出现异常,另一个人就不会收到钱

   

一个人少钱,另一个人却没有多钱,导致钱丢失了

   

   

   

   

4、解决方法

   

添加事务管理,当出现异常时进行回滚

   

   

   

   

   

   

   

   

   

【made by siwuxie095】

Spring事务管理

标签:std   事务管理器   右键   级别   rman   sql   --   getbean   bsp   

原文地址:http://www.cnblogs.com/siwuxie095/p/7417314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!