spring注解事务及事务回滚失败的原因
背景
spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。
自动提交(AutoCommit)与连接关闭时的是否自动提交
自动提交
默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则隐式的提交事务,如果
执行失败则隐式的回滚事务。
spring注解事务的实现
maven创建一个普通项目,当然web项目也可以,我这里是一个web项目
pom.xm如下,本身是用不到这么多jar,直接从项目中拷贝的,懒得删。
<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.bamboo</groupId><artifactId>anoTest</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>anoTest Maven Webapp</name><url>http://maven.apache.org</url><repositories><repository><id>nexus_public</id><name>nexus_public</name><url>http://repo.maven.apache.org/maven2/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>nexus_public</id><name>nexus_public</name><!-- <url>http://repository.jboss.org/nexus/content/repositories/root_repository/maven2/</url> --><url>http://repo.maven.apache.org/maven2/</url><layout>default</layout><snapshots><enabled>false</enabled></snapshots><releases><updatePolicy>never</updatePolicy></releases></pluginRepository></pluginRepositories><!-- 项目属性 --><properties><!-- jar 版本设置 --><spring.version>4.1.0.RELEASE</spring.version><shiro.version>1.2.3</shiro.version><mybatis.version>3.2.8</mybatis.version><mybatis-spring.version>1.2.2</mybatis-spring.version><mysql.version>5.1.26</mysql.version><druid.version>1.0.9</druid.version><junit.version>3.8.1</junit.version><log4j.version>1.2.17</log4j.version><slf4j.version>1.7.5</slf4j.version><poi.version>3.10-FINAL</poi.version><commons-lang3.version>3.1</commons-lang3.version><commons-io.version>2.4</commons-io.version><commons-codec.version>1.8</commons-codec.version><commons-fileupload.version>1.3.1</commons-fileupload.version><commons-beanutils.version>1.8.3</commons-beanutils.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><jdk.version>1.7</jdk.version></properties><dependencies><!-- spring相关包 --><!-- Spring --><dependency><groupId>org.apache.tomcat</groupId><artifactId>servlet-api</artifactId><version>6.0.37</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</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-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</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-orm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!-- 切面jar --><dependency><groupId>aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.5.4</version></dependency><!-- javax提供的annotation,注入的注解jar --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- 日志架包 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>1.9.13</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--springMVC 依赖json解析jar --><dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.1.0</version> </dependency> <!--Apache Shiro所需的jar包 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro.version}</version></dependency><!-- <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>${shiro.version}</version></dependency> --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro.version}</version></dependency><!-- <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-quartz</artifactId><version>${shiro.version}</version></dependency> --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency><!-- 数据库连接dbcp --><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId> <version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis-spring.version}</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- fileupload的jar --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons-io.version}</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>${commons-fileupload.version}</version></dependency><!-- apache 常用包 --><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.8.3</version><type>jar</type><scope>compile</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.1</version><type>jar</type><scope>compile</scope></dependency><!-- 页面装饰 --><dependency><groupId>opensymphony</groupId><artifactId>sitemesh</artifactId><version>2.4.2</version></dependency><!-- jstl --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- 缓存ehcache --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-core</artifactId><version>2.8.3</version></dependency><!-- ehcache缓存jar --><!-- <dependency> <groupId>com.googlecode.ehcache-spring-annotations</groupId> <artifactId>ehcache-spring-annotations</artifactId> <version>1.2.0</version> <type>jar</type> <scope>compile</scope></dependency> --></dependencies><build><finalName>onedollar</finalName></build>
</project>
spring.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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"xmlns:cache="http://www.springframework.org/schema/cache"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsdhttp://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"><!-- 自动扫描 --> <context:component-scan base-package="anotest" /> <!-- 定义一个数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://127.0.0.1/shiro" /><property name="username" value="root" /><property name="password" value="root" /><property name="initialSize" value="3" /><!-- initial connections --><property name="maxActive" value="10" /><!-- MAX connections --><property name="maxIdle" value="5" /><!-- MAX idle connections --><property name="minIdle" value="2" /><!-- MIN idle connections --><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><property name="validationQuery" value="select 1" /><property name="timeBetweenEvictionRunsMillis" value="20000" /><property name="numTestsPerEvictionRun" value="100" /></bean><!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件 --> <property name="mapperLocations" value="classpath:anotest/mapper/*.xml"></property> <property name="typeAliasesPackage" value="anotest" /></bean> <!-- DAO接口所在包名,Spring会自动查找其下的类 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="anotest.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"> </bean> <!-- enables scanning for @Transactional annotations --> <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" /> <!-- 配置事物的拦截方式 --><!-- <tx:advice id="transAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="delete*" propagation="REQUIRED" /><tx:method name="insert*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="add*" propagation="REQUIRED" /><tx:method name="modify*" propagation="REQUIRED" /><tx:method name="remove*" propagation="REQUIRED" /><tx:method name="find*" propagation="SUPPORTS" /><tx:method name="get*" propagation="SUPPORTS" /><tx:method name="select*" propagation="SUPPORTS" /><tx:method name="query*" propagation="SUPPORTS" /><tx:method name="*" propagation="SUPPORTS" /></tx:attributes></tx:advice> --><!-- 事物配置扫描包 --><!-- <aop:config proxy-target-class="true"><aop:pointcut expression="execution(* anotest.*impl.*(..))" id="transcationPointcut" /><aop:advisor advice-ref="transAdvice" pointcut-ref="transcationPointcut" /></aop:config> --></beans>
代码片段
创建包名
anotest.dao
anotest.mapper
anotest.service.impl
LogDao.java
package anotest.dao;import anotest.Log;/*** log页面表 数据库处理类*/
public interface LogDao {void add(Log log);
}
LogMapper.xml
<?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="anotest.dao.LogDao"><resultMap type="Log" id="Log"><id column="LOG_ID" property="logId" javaType="java.lang.Long" jdbcType="BIGINT"/><result column="IMEI_CODE" property="imeiCode" javaType="java.lang.String" jdbcType="VARCHAR"/><result column="DAY_TIME" property="dayTime" javaType="java.lang.String" jdbcType="VARCHAR"/>
</resultMap><!-- 全部字段,一般用于明细查询 -->
<sql id="AllColumnlist">
LOG_ID,IMEI_CODE,DAY_TIME
</sql><!-- 常见字段,一般用于列表查询,可能不包含备注之类的字段 -->
<sql id="CommonColumnlist">
LOG_ID,IMEI_CODE,DAY_TIME
</sql><insert id="add" parameterType="Log" useGeneratedKeys="true" keyProperty="LogId">insert into T_LOG (<if test="logId!=null">LOG_ID,</if>IMEI_CODE,DAY_TIME) values (<if test="logId!=null">#{logId,jdbcType = BIGINT},</if>#{imeiCode,jdbcType = VARCHAR},#{dayTime,jdbcType = VARCHAR})
</insert><delete id="delete">delete from T_LOG <where>Log_ID=#{0}</where>
</delete><select id="get" resultMap="Log">select <include refid="AllColumnlist"/> from T_LOG<where>LOG_ID=#{0}</where>
</select><select id="getLogByCode" parameterType="java.lang.String" resultMap="Log">select * from T_LOG<where>IMEI_CODE=#{0}</where>
</select></mapper>
Log.java
package anotest;public class Log {private static final long serialVersionUID = 1l;/*Auto generated properties start*///log-idprivate Long logId;//IMEI编号private String imeiCode;//年月日private String dayTime;/*Auto generated methods start*/public Log() {}/*** @param imeiCode* @param dayTime*/public Log(String imeiCode, String dayTime) {super();this.imeiCode = imeiCode;this.dayTime = dayTime;}/*Auto generated methods end*//*Customized methods start*//*Customized methods end*/public Long getLogId() {return logId;}public void setLogId(Long logId) {this.logId = logId;}public String getImeiCode() {return imeiCode;}public void setImeiCode(String imeiCode) {this.imeiCode = imeiCode;}public String getDayTime() {return dayTime;}public void setDayTime(String dayTime) {this.dayTime = dayTime;}@Overridepublic String toString() {return "Log [logId=" + logId + ", imeiCode=" + imeiCode + ", dayTime="+ dayTime + "]";}}
TestService.java
package anotest.service;import anotest.Log;/** * @ClassName: TestService * @Description: TODO(这里用一句话描述这个类的作用) * @author bamboo <a href="mailto:zjcjava@163.com?subject=hello,bamboo&body=Dear Bamboo:%0d%0a描述你的问题:">Bamboo</a>* @date 2017年3月7日 上午10:17:06 * @since*/public interface TestService {public void addCatch() throws Exception;public void addTest();
}
TestServiceImpl.java
package anotest.service.impl;import java.text.SimpleDateFormat;
import java.util.Date;import javax.annotation.Resource;import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import anotest.Log;
import anotest.dao.LogDao;
import anotest.service.TestService;/** * @ClassName: TestServiceImpl * @Description: TODO(这里用一句话描述这个类的作用) * @author bamboo <a href="mailto:zjcjava@163.com?subject=hello,bamboo&body=Dear Bamboo:%0d%0a描述你的问题:">Bamboo</a>* @date 2017年3月7日 上午10:38:42 * @since*/
@Service
//默认将类中的所有函数纳入事务管理.
@Transactional
public class TestServiceImpl implements TestService{@Resourceprivate LogDao logDao;/**** 捕获异常后但是不抛出去是无法执行回滚事务的* 建议:用本方式写,使上层方法能够检测到数据插入失败,因此必须抛出异常,然后在调用它的方法中捕获异常并提示用户数据提交失败* @throws Exception */@Transactionalpublic void addCatch() throws Exception {// TODO Auto-generated method stubtry {SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");String dayTime=format.format(new Date());Log log =new Log("ABCD", dayTime);log.setLogId(System.currentTimeMillis());System.out.println(log.toString());// 调用Dao执行插入操作logDao.add(log);//正常常数据log.setDayTime(dayTime+"yyyyyyyyyyyyyyyyyyy");// 调用Dao执行插入操作logDao.add(log);//异常数据} catch (Exception e) {// TODO Auto-generated catch blockSystem.out.println("插入失败");//throw new Exception(e);//注意:正常环境中必须去掉本行注释,当把这行去掉注释事务回滚就会起作用}}/******* 运行时异常不作捕获则则能够正常执行回滚事务*/@Transactionalpublic void addTest() {// TODO Auto-generated method stubSimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");String dayTime=format.format(new Date());Log log =new Log("ABCD", dayTime);log.setLogId(System.currentTimeMillis());System.out.println(log.toString());// 调用Dao执行插入操作logDao.add(log);log.setDayTime(dayTime+"yyyyyyyyyyyyyyyyyyy");// 调用Dao执行插入操作logDao.add(log);//异常数据}}
测试类
ContextConfig.java
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //指定bean注入的配置文件
@ContextConfiguration(locations = { "classpath:spring.xml" })
//使用标准的JUnit @RunWith注释来告诉JUnit使用Spring TestRunner
@RunWith(SpringJUnit4ClassRunner.class)
public class ContextConfig extends AbstractJUnit4SpringContextTests {}
TestCase.java
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;import anotest.service.TestService;public class TestCase extends ContextConfig {@Autowired private TestService testService;@Testpublic void getTimestampTest() throws Exception{ testService.addCatch();//1捕获异常的方法,注释掉异常抛出则不会回滚testService.addTest();//2没有任何捕获,能够正常回滚}
}
测试结果
当注释掉注释//2所在的行只执行addCatch()方法时
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Log [logId=1488871162669, imeiCode=ABCD, dayTime=20170307]
插入失败
插入失败,但是我们看数据库,依然会有数据被插入了
mysql> select * from t_log;
+---------------+-----------+------------+
| LOG_ID | IMEI_CODE | DAY_TIME |
+---------------+-----------+------------+
| 1488871162669 | ABCD | 2017-03-07 |
+---------------+-----------+------------+
1 row in set (0.00 sec)
当注释掉注释//1所在的行只执行addTest()方法时
OUTPUT:
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Log [logId=1488871460315, imeiCode=ABCD, dayTime=20170307]
看数据库,显然数据没有被插入,而是发生了回滚
mysql> select * from t_log;
+---------------+-----------+------------+
| LOG_ID | IMEI_CODE | DAY_TIME |
+---------------+-----------+------------+
| 1488871162669 | ABCD | 2017-03-07 |
+---------------+-----------+------------+
1 row in set (0.00 sec)
我们在回到addCatch()方法,把下面这行的注释去掉
//throw new Exception(e);//注意:正常环境中必须去掉本行注释,当把这行去掉注释事务回滚就会起作用
运行测试
OUTPUT:
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Log [logId=1488871709355, imeiCode=ABCD, dayTime=20170307]
插入失败
查看表数,可以看到这次数据并没有被插入
mysql> select * from t_log;
+---------------+-----------+------------+
| LOG_ID | IMEI_CODE | DAY_TIME |
+---------------+-----------+------------+
| 1488871162669 | ABCD | 2017-03-07 |
+---------------+-----------+------------+
1 row in set (0.00 sec)
结论
spring的事务只有在触发运行时异常时才会发生回滚,并且这个异常是在切面中是可以被事务管理器捕获到的,如果我们自己在方法体中捕获而不把这个异常抛出(不通知事务管理器)它就不会除非事务回滚。因此在dao层基本不处理数据库插入异常。
其他原因
mysql数据库引擎的问题
mysql数据库引擎分为两种
innodb:支持事务和索引
myisam:不支持事务和索引,因此这种类型的引擎即使你的代码写的是正确的但是依然不会触发事务回滚。
配置文件扫描的问题
因为spring的容器(applicationContext)和springMVC的(applicationContext)是不同的。
spring容器加载得时候,优先加载ServletContextListener(对应spring.xml)产生的父容器,而springMVC(对应springMVC.xml)产生的是子容器。子容器Controller进行扫描装配时装配的@Service注解的实例是没有经过事务加强处理,
即没有事务处理能力的Service。而父容器进行初始化的Service是保证事务的增强处理能力的。如果不在子容器中将Service除去掉,此时得到的将是原样的无事务处理能力的Service。
所以,我们应把扫描Service的工作放在spring.xml中。让Service和事务注解存在于同一个容器中,这样配置的事务注解就能起作用了。也就是说把这个配置从
springMVC.xml中移到spring.xml的配置中。事务不回滚的问题就能解决了。
本demo下载
http://download.csdn.net/detail/zjcjava/9773010
spring注解事务及事务回滚失败的原因相关推荐
- 详解spring事务失效和回滚失败的场景
详解spring事务失效和回滚失败的场景 详解spring事务失效和回滚失败的场景 前言 一 .事务不生效 1.访问权限问题 2. 方法用final修饰 3.方法的内部调用 3.1 新加一个Servi ...
- Spring事务回滚失败
下面是一个回滚事务的案例 需求是:转账失败后 转账的事务会回滚,日志事务不会回滚 出现的问题是: 日志事务开启了@Transactional(propagation = Propagation.REQ ...
- Spring不同事务管理方式与声明式事务管理局部回滚处理方案
Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataS ...
- oracle 事务未正常回滚,Spring事务没有回滚异常(Oracle JNDI数据源)
我在 Spring MVC 3.1项目中使用基于注释的事务,并且在抛出异常时我的事务没有被回滚. 这是我的服务代码 @Service public class ImportService { @Aut ...
- spring事务管理中,用try-catch处理了异常,事务也会回滚?
在平时的开发中,如果在事物方法中用 try-catch处理了异常,那么spring aop不能捕获到异常信息,从而会导致spring不能对事务方法正确的进行管理,不能及时回滚错误信息. 下面用代码演示 ...
- (转)使用Spring注解方式管理事务与传播行为详解
http://blog.csdn.net/yerenyuan_pku/article/details/52885041 使用Spring注解方式管理事务 前面讲解了怎么使用@Transactional ...
- JUnit测试类完成后事务是默认 回滚的。只能查询数据,不能增删改。
JUnit测试类完成后事务是默认 回滚的.只能查询数据,不能增删改. 在测试类或者测试方法上面加上注解 @Rollback(false) 表示事物不回滚,这样数据就可以提交到数据库中了. 转载于:h ...
- php中对MYSQL操作之事务控制,回滚
<?php //事务控制,回滚 //创建一个mysqli对象 $mysqli = new MySQLi("主机名","mysql用户名","密码 ...
- mysql数据库回滚日志_MySQL中是如何实现事务提交和回滚的?
什么是事务 事务是由数据库中一系列的访问和更新组成的逻辑执行单元 事务的逻辑单元中可以是一条SQL语句,也可以是一段SQL逻辑,这段逻辑要么全部执行成功,要么全部执行失败 举个最常见的例子,你早上出去 ...
最新文章
- Java项目:网上电商系统(java+SSM+mysql+maven+tomcat)
- java get resttemplate 请求传递数组_RestTemplate入门
- Plant Com:中科院遗传发育所白洋组开发定量检测宿主微生物组的HA-QAP技术(王二涛点评)...
- movie bookmark
- 你真的懂用户画像吗?
- 如何用堆栈和循环结构代替递归调用--递归转换为非递归的10条军规
- graphpad prism怎么添加图例_Graphpad官网刚刚升级了!听说,新功能吊打R语言...........
- Android 如何添加一种锁屏方式
- LeetCode 83. 删除排序链表中的重复元素(链表)
- vantUI组件:Grid宫格 - 案例篇
- 验毛坯房要注意什么?
- 设计师所需图标素材网站,不用到处找了,都在这!
- electronjs设置宽度_Js操作DOM元素及获取浏览器高宽的简单方法
- OpenDigg前端开源项目周报1219
- 用jmap和jps查看对象数量
- 1、matplotlib绘制一个简单的图形
- MySQL 中while loop repeat 的基本用法
- 方舟php服务器控制,方舟基本管理命令代码
- linux usb重定向window,基于Linux的USB设备重定向研究.pdf
- 通过黑客代号带你回顾九位世界顶尖的黑客大咖