spring框架(容器框架之一)事务管理

Spring: 容器框架,一站式框架,用于配置bean,并维护bean之间的关系框架,贯穿框架三层。

(本文章属于个人学习经验总结,如果有错误或描述不当的地方欢迎指出讨论)

Spring之事务管理:

一、相关概念

1、什么是事务:事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。

2、事务管理:我们在实际业务场景中,经常会遇到数据频繁修改读取的问题。在同一时刻,不同的业务逻辑对同一个表数据进行修改,这种冲突很可能造成数据不可挽回的错乱,所以我们需要用事务来对数据进行管理。
例子:两个人同时向一个账户里转钱、一个人向另外一个人转钱。

3、并发事务导致的问题
第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。
脏读:一个事务读取到另一个事务未提交的更新数据。
幻读也叫虚读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。
不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。

4、JDBC 中是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。
Hibernate中是通过Transaction进行事务管理处理方法与JDBC中类似。
Spring 中也有自己的事务管理机制,一般是使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。

二、Spring的事务管理方式:

两种方式:1)编程事务管理

                    2)声明事务管理

                         1、基于xml配置文件

                         2、基于注解

举例:搭建转账环境(说明事务管理重要和相关操作)(采用非注释)

第一步:Mysql下创建数据库表:


第二步:

创建dao类:OrdersDao

package com.sp.dao;

import org.springframework.jdbc.core.JdbcTemplate;
 
public class OrdersDao {
    private JdbcTemplate jdbctemplate ;
	public JdbcTemplate getJdbctemplate() {
		return jdbctemplate;
	}
	public void setJdbctemplate(JdbcTemplate jdbctemplate) {
		this.jdbctemplate = jdbctemplate;
	}
	//向一个账户里转钱进去
	public 	void lessMoney() {
		String sql = "update acount set salary =salary-? where username =?";
		jdbctemplate.update(sql,1000,"小王");
		
	}
	//向一个账户里转钱出去
	public void moreMoney() {
		String sql = "update acount set salary =salary+? where username =?";
		jdbctemplate.update(sql,1000,"小马");
		
	} 
}

创建Service类:

package com.sp.service;

import com.sp.dao.OrdersDao;

public class OrdersService {
      private OrdersDao ordersDao;

	public OrdersDao getOrdersDao() {
		return ordersDao;
	}

	public void setOrdersDao(OrdersDao ordersDao) {
		this.ordersDao = ordersDao;
	}
    public void accountMoney() {
    	ordersDao.lessMoney();
    	int i = 10/0;
    	ordersDao.moreMoney();
    }
}

测试类:

package com.sp.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("bean2.xml");
		OrdersService ordersService = (OrdersService) context.getBean("ordersService");
		//System.out.println(book);
		ordersService.accountMoney();
	}
}

配置xml文件:
 <!-- 配置连接池 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        
        <!-- 注入里面的属性 -->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="lky123456"></property>
        </bean>
        
        <bean id="ordersService" class="com.sp.service.OrdersService">
        <property name="ordersDao" ref="ordersDao"></property>
        </bean>
        
        <bean id="ordersDao" class="com.sp.dao.OrdersDao">
        <property name="jdbctemplate" ref="jdbctemplate"></property>
        </bean>
        
        <bean id="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!-- 配置事务管理器 -->
        
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
        <property name="dataSource" ref="dataSource"></property>
        
        
        </bean>
        
        <!-- 配置事务增强 -->
        <tx:advice id="txadvice" transaction-manager="transactionManager">
        <!-- 做事务的操作 -->
           <tx:attributes>
                 <!-- 设置事务方法匹配规则 -->
                <tx:method name="account*"/>
        
           </tx:attributes>
        
        </tx:advice>
         
         <!-- 配置切面 -->
         
         <aop:config>
            <aop:pointcut expression="execution(* com.sp.service.OrdersService.*(..))" id="pointcut1"/>
            
            <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>   
         
         </aop:config>
输出测试:运行测试类时,如果没有在xml文件中配置事务管理器相关信息,则运行到service类的account方法时,则会出现小王的salary减少1000,小马的没有增加1000的结果出现。

如果加上了事务管理器,则会出现数据没有改变的结果。

说明了Spring事务管理器防止了这样的事务的发生。


附上:

Spring 配置xml文件的全约束
( <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans> )











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值