zoukankan      html  css  js  c++  java
  • Spring 事务入门

    定义:

    一系列的动作,被当成一个单独的工作单元,要么都完成,要么全部不起作用(失败回滚)。

    之前的事务处理:JDBC与Hibernate中的事务处理——与try...catch...finally...一起用。
    Spring中的事务处理:编程式,声明式。
    Spring从事务管理的API中抽象出一套独立事务机制。事务管理代码能独立于特点的具体技术。

    使用方法:

    建立beans.xml

    准备工作:配置数据源对象。

    <!-- 生成数据连接池 -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
        <property name="minPoolSize" value="${minPoolSize}"></property>
        <property name="maxPoolSize" value="${maxPoolSize}"></property>
        <property name="initialPoolSize" value="${initialPoolSize}"></property>
    </bean>
    
    <!-- 生成jdbcTemplate -->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    1.配置事务管理器。

    DataSourceTransactionManager类
    dataSource属性注入

    <!-- 配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    2.在配置文件中启用事务注解 

    把tx命名空间加进来。

     

    <!-- 启动事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

     3.添加事务注解。在类中使用的方法上添加这个注解:@Transactional 

      @Transactional//事务注解    
        @Override
        public void delete(String code) {
            workDao.deleteByInfoCode(code);
            infoDao.delete(code);        
        }

    下面看一个实例:

    准备工作:导入c3p0、Spring框架、Mysql的jar包,并配置好

    db.properties

    driverClass=com.mysql.jdbc.Driver
    jdbcUrl=jdbc:mysql://localhost:3306/mydb
    user=root
    password=
    minPoolSize=5
    maxPoolSize=20
    initialPoolSize=5

    beans.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: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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    
    <!--加载数据库配置文件 db.properties-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 生成连接池 -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
        <property name="minPoolSize" value="${minPoolSize}"></property>
        <property name="maxPoolSize" value="${maxPoolSize}"></property>
        <property name="initialPoolSize" value="${initialPoolSize}"></property>
    </bean>
    
    <!-- 生成jdbcTemplate -->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    </beans>

    1.做两个接口IInfoDao和IWorkDao

    package maya.dao;
    
    public interface IInfoDao {
        public void delete(String code);
    }
    package maya.dao;
    
    public interface IWorkDao {
        public void deleteByInfoCode(String code);
    }

    2.做两个类继承以上两个接口:InfoDao和WorkDao

    package maya.daolmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import maya.dao.IInfoDao;
    @Repository
    public class InfoDao implements IInfoDao {
       
      @Autowired
    //自动装配beans.xml中的jdbcTemplate private JdbcTemplate jdbcTemplate;
      @Override
    public void delete(String code) { String sql = "delete from info where code=?"; jdbcTemplate.update(sql,code); //故意写一个错误代码 int n = 5/0; } }
    package maya.daolmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import maya.dao.IWorkDao;
    @Repository
    public class WorkDao implements IWorkDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        @Override
        public void deleteByInfoCode(String code) {
            String sql = "delete from work where infoCode=?";
            jdbcTemplate.update(sql,code);        
        }
    
    }

    3.向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: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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

    <!--扫描以下包里的类,以备使用--> <context:component-scan base-package="maya.daolmpl,maya.servicelmpl"></context:component-scan> <context:property-placeholder location="classpath:db.properties"/> <!-- 生成连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成jdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务管理器 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 启动事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>

    4.建立业务接口并用类继承

    IInfoService接口

    package maya.service;
    
    public interface IInfoService {
        public void delete(String code);
    }

    InfoService类

    package maya.servicelmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.daolmpl.WorkDao;
    import maya.service.IInfoService;
    @Service
    public class InfoService implements IInfoService {
        @Autowired
        private IWorkDao workDao;
        @Autowired
        private IInfoDao infoDao;
        
        @Transactional//为以下方法添加事务注解    
        @Override
        public void delete(String code) {
            workDao.deleteByInfoCode(code);
            infoDao.delete(code);        
        }
    }

    5.创建测试类并运行

    package maya.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.service.IInfoService;
    
    public class Test {
        private static ApplicationContext context = null;
        private static IInfoDao infoDao = null;
        private static IWorkDao workDao = null;
        private static IInfoService infoService = null;
    
        static {
            context = new ClassPathXmlApplicationContext("beans.xml");
            infoDao = (IInfoDao)context.getBean("infoDao");
            workDao = (IWorkDao)context.getBean("workDao");
            infoService = (IInfoService)context.getBean("infoService");        
        }    
        
        public static void main(String[] args) {
            infoService.delete("a004");
        }
    }

    结果(报错,由于除数为0):

    Exception in thread "main" java.lang.ArithmeticException: / by zero

    查看数据库表,并未删除成功

    把事务取消掉,比如删除事务注解

    package maya.servicelmpl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import maya.dao.IInfoDao;
    import maya.dao.IWorkDao;
    import maya.daolmpl.WorkDao;
    import maya.service.IInfoService;
    @Service
    public class InfoService implements IInfoService {
        @Autowired
        private IWorkDao workDao;
        @Autowired
        private IInfoDao infoDao;
        
        //@Transactional,事务注解注销掉
        @Override
        public void delete(String code) {
            workDao.deleteByInfoCode(code);
            infoDao.delete(code);        
        }
    }

    再次运行查看结果:依然报错

    Exception in thread "main" java.lang.ArithmeticException: / by zero

    查看数据库,“a004”已被删除

  • 相关阅读:
    Java-数据字符串进行四舍五入
    Git本地安装及汉化
    Navicat安装教程
    Jdk+maven安装
    系列文章
    @PathVariable
    feign组件
    Lombok
    常见Jar包的用途
    iOS archive(归档)的总结
  • 原文地址:https://www.cnblogs.com/jonsnow/p/6652810.html
Copyright © 2011-2022 走看看