spring中的事物

spring中的事物

【1】事物的概念

事务的概念:事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败。

【2】事务的特性

原子性(Atomicity):当事务结束,它对所有资源状态的改变都被视为一个操作,这些操作要不同时成功,要不同时失败;
一致性(Consistency):操作完成后,所有数据必须符合业务规则,否则事务必须中止;
隔离性(Isolation):事务以相互隔离的方式执行,事务以外的实体无法知道事务过程中的中间状态;
持久性(Durable):事务提交后,数据必须以一种持久性方式存储起来。

【3】不考虑事务引发的安全

(1)脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。
(2)不可重复读:在同一个事务中,多次读取同一数据返回的结果有所不同。
(3)幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录。

【4】spring的事物管理机制

Spring事物管理高层抽象主要包括三个接口,spring的失误主要是由他们共同完成的:

PlatformTransactionManager 事务管理器(提交、回滚事务)
TransactionDefinition 事务定义信息(隔离、传播、超时、只读)
TransactionStatus 事务具体运行状态

【5】PlatformTransactionManager接口

PlatformTransactionManager 该接口提供了三个方法:
  commit:提交事物
  rollback:回滚事物
  getTransaction:获取事物的状态

Spring为不同的持久性框架提供了不同的 PlatformTransactionManager 接口实现:
SpringJDBC 或 iBatis 框架:
  org.springframework.jdbc.datasource.DataSourceTransactionManager
hibernate:
  org.springframework.orm.hibernate3.HibernateTransactionManager
  org.springframework.orm.hibernate4.HibernateTransactionManager
  org.springframework.orm.hibernate5.HibernateTransactionManager
JPA:
  org.springframework.orm.jpa.JpaTransactionManager
JDO:
  org.springframework.orm.jdo.JdoTransactionManager
JTA:
  org.springframework.transaction.jta.JtaTransactionManager

org.springframework.jdbc.datasource.DataSourceTransactionManager针对JDBCTemplate,Mybatis,使用Connection进行事物控制:
  开启事物:connection.setAutoCommit(false);
  提交事物:connection.commit();
  回滚事物:connection.rollback();

【6】TransactionDefinition接口

事务隔离级别(五种):
隔离级别 :含义
default :使用后端数据库默认的隔离级别(spring中的选择项)
read_uncommited:  允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读
read_committed :允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生
repeatable_read:  对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生
serializable :完全服从acid的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的

注: 其中,mysql默认采用repeatable_read隔离级别;oracle默认采用read_committed隔离级别

七种事务传播行为:
事务传播行为 :含义
required :支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
supports :支持当前事务,如果当前没有事务,就以非事务方式执行
mandatory :支持当前事务,如果当前没有事务,就抛出异常。
requires_new :以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
not_supported:  以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
never :以非事务方式执行,如果当前存在事务,则抛出异常。
nested:   如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与required类似的操作。拥有多个可以回滚的保存点,内部回滚不会对外部事务产生影响。只对datasourcetransactionmanager有效。

【7】TransactionStatus接口

TransactionStatus接口用来记录事务的状态。该接口定义了一组方法,用来获取或判断事务的相应状态信息。
平台事务管理器(PlatformTransactionManager)会根据TransactionDefinition中定义的事务信息(包括隔离级别、传播行为)来进行事务的管理,在管理的过程中事务可能产生了保存点或事务是新的事务等情况,那么这些信息都会记录在TransactionStatus的对象中。

【8】事务超时/回滚规则

事务超时 :
为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。

回滚规则 :
事务五边形的最后一个方面是一组规则,这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)。但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。

【9】业务中的事物案例

业务1:取款是一个事物操作,打印凭条是一个事物

业务2:删除客户信息之后,同时需要删除用的订单信息,一个事物。 //客户信息删除了,订单信息就多余了

【9】基于xml配置声明式事物

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `account` VALUES (‘1‘, ‘aaa‘, ‘1000‘);
INSERT INTO `account` VALUES (‘2‘, ‘bbb‘, ‘1000‘);
INSERT INTO `account` VALUES (‘3‘, ‘ccc‘, ‘1000‘);

数据库

package com.tencent.mapper;

import org.apache.ibatis.annotations.Param;

public interface AccountMapper {

    void outMoney(@Param("money") double money ,@Param("name") String name);
    void  inMoney(@Param("money") double money ,@Param("name")String name);

}

AccountMapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.tencent.mapper.AccountMapper">
    <resultMap type="People" id="people">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="money" property="money" />
    </resultMap> 

    <!-- 转出 -->
    <update id="outMoney" >
    update account set money=money-#{money} where name=#{name};
    </update>

    <!-- 转入 -->
    <update id="inMoney" parameterType="People">
    update account set money=money+#{money} where name=#{name};
    </update>

</mapper>

AccountMapper.xml

package com.tencent.pojo;

public class People {

    private int id;
    private String name;
    private double  money;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        long temp;
        temp = Double.doubleToLongBits(money);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        People other = (People) obj;
        if (id != other.id)
            return false;
        if (Double.doubleToLongBits(money) != Double.doubleToLongBits(other.money))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "People [id=" + id + ", name=" + name + ", money=" + money + "]";
    }
    public People(int id, String name, double money) {
        super();
        this.id = id;
        this.name = name;
        this.money = money;
    }
    public People() {
        super();
    }

}

People.java

package com.tencent.service;

public interface AccountService {

    /**
     *
     * @方法的说明:
     * @author 张瑛
     * @Time 2019年5月18日 下午6:52:22
     * @param outName   转出人姓名
     * @param inMoney    转入人姓名
     * @param money        转账金额
     */
    public void transfer(String outName,String inMoney ,double money);

}

AccountService.java

package com.tencent.service.impl;

import com.tencent.mapper.AccountMapper;
import com.tencent.service.AccountService;

public class AccountServiceImpl implements AccountService {

    AccountMapper  accountMapper;

    @Override
    public void transfer(String outName, String inName, double money) {
        accountMapper.outMoney(money, outName);
        //异常
        //int i=1/0;
        accountMapper.inMoney(money, inName);

    }

    public AccountMapper getAccountMapper() {
        return accountMapper;
    }

    public void setAccountMapper(AccountMapper accountMapper) {
        this.accountMapper = accountMapper;
    }
}

AccountServiceImpl.java

package com.tencent.test;

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

import com.tencent.service.AccountService;

public class TransactionTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationcontext.xml");
        AccountService bean = (AccountService) context.getBean("accountServiceImpl");

        bean.transfer("aaa", "bbb", 100d);

    }
}

TransactionTest.java

<?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: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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd"
        default-autowire="byName">
  <!-- 配置属性文件 -->
  <context:property-placeholder location="classpath:db.properties"/>

  <!-- 配置业务层类  -->
  <bean id="accountServiceImpl" class="com.tencent.service.impl.AccountServiceImpl">
       <property name="accountMapper" ref="accountMapper"></property>
  </bean>

  <!-- 配置数据源 -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="${mysql.driver}"/>
     <property name="url" value="${mysql.url}"/>
     <property name="username" value="${mysql.username}"/>
     <property name="password" value="${mysql.password}"/>
  </bean>

  <!-- 配置工厂 -->
  <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <!-- 配置别名 -->
      <property name="typeAliasesPackage" value="com.tencent.pojo"></property>
  </bean>

  <!-- 配置mapper扫描 -->
  <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="sqlSessionFactoryBeanName" value="factory"></property>
       <property name="basePackage" value="com.tencent.mapper"></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="transfer" read-only="false" isolation="DEFAULT" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
     <!-- 配置切面 -->
    <aop:config>
        <!-- 配置切入点 -->
        <aop:pointcut expression="bean(*ServiceImpl)" id="mycut"/>
        <!-- <aop:pointcut expression="execution(* com.tencent.service.*.*(..))" id="poi"/> -->
        <!-- 配置切面 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="mycut"/>
    </aop:config>

  </beans>

applicationcontext.xml

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf8
mysql.username=root
mysql.password=root

db.properties

# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=error, CONSOLE,LOGFILE

log4j.logger.com.bjsxt.mapper.FlowerMapper=debug
log4j.logger.com.bjsxt.controller.MyContorlller=debug

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%c-%d{yyyy/MMM/dd HH:mm:ss}- %m%n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%c-%d{yyyy/MMM/dd HH:mm:ss}- %m%n

log4j.properties

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tencent</groupId>
  <artifactId>SSM_001</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

     <!-- 自定义属性标签 -->
    <properties>
        <servlet-version>3.0.1</servlet-version>
        <jsp-version>2.2</jsp-version>
        <jstl-version>1.2</jstl-version>
        <spring-version>4.1.6.RELEASE</spring-version>
        <aspectjweaver-version>1.8.6</aspectjweaver-version>
        <mybatis-version>3.2.7</mybatis-version>
        <mybatis-spring-version>1.2.3</mybatis-spring-version>
        <log4j-version>1.2.17</log4j-version>
        <mysql-connector-java-version>5.1.38</mysql-connector-java-version>
        <jackson-version>2.4.3</jackson-version>
        <commons-fileupload-version>1.3.1</commons-fileupload-version>
        <tomcat-version>2.2</tomcat-version>
        <dubbo-version>2.5.3</dubbo-version>
        <zkClient-version>0.10</zkClient-version>
        <ftpclient-version>3.3</ftpclient-version>
        <jedis-version>2.8.1</jedis-version>
        <ego-version>0.0.1-SNAPSHOT</ego-version>
        <httpclient-version>4.4.1</httpclient-version>
        <pagehelper-version>4.1.6</pagehelper-version>
    </properties>
        <dependencies>
            <!-- servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet-version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp-version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl-version}</version>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectjweaver-version}</version>
            </dependency>
            <!-- mybatis和spring整合 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis-spring-version}</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis-version}</version>
            </dependency>
            <!-- log4j 日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j-version}</version>
            </dependency>
            <!-- mysql 驱动类 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java-version}</version>
            </dependency>
            <!-- jackson -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-version}</version>
            </dependency>
        </dependencies>

</project>

pom.xml

【10】基于注解配置声明式事物

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `account` VALUES (‘1‘, ‘aaa‘, ‘1000‘);
INSERT INTO `account` VALUES (‘2‘, ‘bbb‘, ‘1000‘);
INSERT INTO `account` VALUES (‘3‘, ‘ccc‘, ‘1000‘);

数据库

package com.tencent.mapper;

import org.apache.ibatis.annotations.Param;

public interface AccountMapper {

    void outMoney(@Param("money") double money ,@Param("name") String name);
    void  inMoney(@Param("money") double money ,@Param("name")String name);

}

AccountMapper.java

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.tencent.mapper.AccountMapper">
    <resultMap type="People" id="people">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="money" property="money" />
    </resultMap> 

    <!-- 转出 -->
    <update id="outMoney" >
    update account set money=money-#{money} where name=#{name};
    </update>

    <!-- 转入 -->
    <update id="inMoney" parameterType="People">
    update account set money=money+#{money} where name=#{name};
    </update>

</mapper>

AccountMapper.xml

package com.tencent.pojo;

public class People {

    private int id;
    private String name;
    private double  money;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        long temp;
        temp = Double.doubleToLongBits(money);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        People other = (People) obj;
        if (id != other.id)
            return false;
        if (Double.doubleToLongBits(money) != Double.doubleToLongBits(other.money))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "People [id=" + id + ", name=" + name + ", money=" + money + "]";
    }
    public People(int id, String name, double money) {
        super();
        this.id = id;
        this.name = name;
        this.money = money;
    }
    public People() {
        super();
    }

}

People.java

package com.tencent.service;

public interface AccountService {

    /**
     *
     * @方法的说明:
     * @author 张瑛
     * @Time 2019年5月18日 下午6:52:22
     * @param outName   转出人姓名
     * @param inMoney    转入人姓名
     * @param money        转账金额
     */
    public void transfer(String outName,String inMoney ,double money);

}

AccountService.java

package com.tencent.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tencent.mapper.AccountMapper;
import com.tencent.pojo.People;
import com.tencent.service.AccountService;
/**
 * @Transactional 用在类上对该类中的所有方法有效  用在某一个方法上只对该方法有效
 */
@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    AccountMapper  accountMapper;

    @Transactional
    public void transfer(String outName, String inName, double money) {
        accountMapper.outMoney(money, outName);
        //异常
        int i=1/0;
        accountMapper.inMoney(money, inName);

    }

}

AccountServiceImpl.java

package com.tencent.test;

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

import com.tencent.service.AccountService;

public class TransactionTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationcontext.xml");
        AccountService bean = (AccountService) context.getBean("accountServiceImpl");

        bean.transfer("aaa", "bbb", 100d);

    }
}

TransactionTest.java

<?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: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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd"
        default-autowire="byName">
  <!-- 配置属性文件 -->
  <context:property-placeholder location="classpath:db.properties"/>

  <!-- 配置业务层类 注解扫描  -->
  <context:component-scan base-package="com.tencent.service.impl"></context:component-scan>

  <!-- 配置数据源 -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="${mysql.driver}"/>
     <property name="url" value="${mysql.url}"/>
     <property name="username" value="${mysql.username}"/>
     <property name="password" value="${mysql.password}"/>
  </bean>

  <!-- 配置工厂 -->
  <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <!-- 配置别名 -->
      <property name="typeAliasesPackage" value="com.tencent.pojo"></property>
  </bean>

  <!-- 配置mapper扫描 -->
  <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="sqlSessionFactoryBeanName" value="factory"></property>
       <property name="basePackage" value="com.tencent.mapper"></property>
  </bean>

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

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

  </beans>

applicationcontext.xml

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf8
mysql.username=root
mysql.password=root

oracle.driver=oracle.jdbc.OracleDriver
oracle.url=jdbc:oracle:thin:@localhost:1521:orcl
oracle.username=scott
oracle.password=123456

db.properties

# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=error, CONSOLE,LOGFILE

log4j.logger.com.bjsxt.mapper.FlowerMapper=debug
log4j.logger.com.bjsxt.controller.MyContorlller=debug

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%c-%d{yyyy/MMM/dd HH:mm:ss}- %m%n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%c-%d{yyyy/MMM/dd HH:mm:ss}- %m%n

log4j.properties

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tencent</groupId>
  <artifactId>SSM_002</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

     <!-- 自定义属性标签 -->
    <properties>
        <servlet-version>3.0.1</servlet-version>
        <jsp-version>2.2</jsp-version>
        <jstl-version>1.2</jstl-version>
        <spring-version>4.1.6.RELEASE</spring-version>
        <aspectjweaver-version>1.8.6</aspectjweaver-version>
        <mybatis-version>3.2.7</mybatis-version>
        <mybatis-spring-version>1.2.3</mybatis-spring-version>
        <log4j-version>1.2.17</log4j-version>
        <mysql-connector-java-version>5.1.38</mysql-connector-java-version>
        <jackson-version>2.4.3</jackson-version>
        <commons-fileupload-version>1.3.1</commons-fileupload-version>
        <tomcat-version>2.2</tomcat-version>
        <dubbo-version>2.5.3</dubbo-version>
        <zkClient-version>0.10</zkClient-version>
        <ftpclient-version>3.3</ftpclient-version>
        <jedis-version>2.8.1</jedis-version>
        <ego-version>0.0.1-SNAPSHOT</ego-version>
        <httpclient-version>4.4.1</httpclient-version>
        <pagehelper-version>4.1.6</pagehelper-version>
    </properties>
        <dependencies>            

            <!-- servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet-version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp-version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl-version}</version>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectjweaver-version}</version>
            </dependency>
            <!-- mybatis和spring整合 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis-spring-version}</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis-version}</version>
            </dependency>
            <!-- log4j 日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j-version}</version>
            </dependency>
            <!-- mysql 驱动类 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java-version}</version>
            </dependency>
            <!-- jackson -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-version}</version>
            </dependency>

        </dependencies>

</project>

pom.xml

 

原文地址:https://www.cnblogs.com/zy-sai/p/10887497.html

时间: 2024-10-27 08:03:54

spring中的事物的相关文章

Spring中的事物管理----HelloWorld

在学习Spring的事物管理之前明白先明白几个概念1什么是事物:事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 例子说明:例如银行转账,A账户转账(转200)到B账户,涉及的动作就是A账户余额减少200,B账户余额增加200,把这两个动作当成一个工作单元,要么两个动作一起完成,要么两个动作都不起用 2事物作用是什么:有四大特性,分别是:原子性(就是多个动作组成一个原子操作,要么一起完成,要么一起不起作用)        一致性(就是事物完成后,数

Spring AOP报错处理 Can not set field to $Proxy 在spring中使用事物或AOP遇到的错误

[转] 解决方法: http://forum.springsource.org/showthread.php?85016-IllegalArgumentException-with-ApplicationContextAware-Proxy 在配置文件中加入proxy-target-class="true" <tx:annotation-driven transaction-manager="transactionManager" proxy-target-c

Spring中的事物管理,用 @Transactional 注解声明式地管理事务

事物: 事务管理是企业级应用程序开发中必不可少的技术,  用来确保数据的 完整性和 一致性. 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 事务的四个关键属性: 原子性:事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成要么完全不起作用. 一致性:一旦所有事务动作完成, 事务就被提交. 数据和资源就处于一种满足业务规则的一致性状态中. 隔离性:可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来,

Spring中的事物管理

1.前瞻: 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作过程中机器突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保证用户和银行的利益都不受损失.在 Spring 中,事务是通过 TransactionDefinition 接口来定义的.该接口包含与事务属性有关的方法. 2.事务隔离级别隔离级别

Spring中的事物管理,基于spring的bean的配置

很多东西与上边的相同,这儿只简介: 导包... 数据库中建立三个表... 建立存放连接数据库的file文件:jdbc.properties: ----------------------------------------------------------------- com.atguigu.spring.tx.xml包下建立, 接口:BookShopDao 类:BookShopDaoImpl 继承于接口,BookShopDao 异常处理类:BookStockException 测试类:JU

spring 中的事物处理机制配置问题

Spring的事务处理机制,给我们编程带来了极大的方便,One-Transaction-Per-Request的实现模式,是本人最为欣赏的! 在之前开始接触Spring的时候,为了实现事务处理的模式,我们在声明事务的时候,一般是这么做 首先声明一个事务模板, <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.Tra

[原创]java WEB学习笔记109:Spring学习---spring中事物管理

博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ------------------------------------------------------------------------------------------------------------------

转:Spring中事物管理

1.什么是事务? 事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物具有四大特性ACID 说到事务,就不得不说其4大特性,主要如下 原子性:(atomicity) 原子性指的是事务是一个不可分割的工作单位,事务中的操作要么全部发生,要么都不发生 (就像物理中,原子是最小不可分割的单位) 一致性:(consistency) 一致性指的是事务前后数据的完整性必须保持一致(比如说,转账:张三账户有2000元,李四账户有2000元,一共4000元 张三项李四转账2000元后,一共还是4

Spring中@Transactional事务回滚实例及源码

一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除某个部门的时候,假设我们默认删除对应的成员.但是在执行的时候可能会出现这种情况,我们先删除部门,再删除成员,但是部门删除成功了,删除成员的时候出异常了.这时候我们希望如果成员删除失败了,之前删除的部门也取消删除.这种场景就可以使用@Transactional事物回滚. 二.checked异常和unc