简介

使用TransactionTemplate 不需要显式地开始事务,甚至不需要显式地提交事务。这些步骤都由模板完成。但出现异常时,应通过TransactionStatus 的setRollbackOnly 显式回滚事务。 

TransactionTemplate 的execute 方法接收一个TransactionCallback 实例。Callback 也是Spring 的经典设计,用于简化用户操作。

TransactionCallback 包含如下方法。

• Object dolnTransaction(TransactionStatus status) 。 

该方法的方法体就是事务的执行体。 

如果事务的执行体没有返回值,则可以使用TransactionCallbackWithoutResultl类的实例。这是个抽象类,不能直接实例化,只能用于创建匿名内部类。它也是TransactionCallback 接口的子接口,该抽象类包含一个抽象方法:

• void dolnTransactionWithoutResult(TransactionStatus status)该方法与dolnTransaction 的效果非常相似,区别在于该方法没有返回值,即事务执行体无须返回值。

transactionTemplate.execute(new TransactionCallback() { 
public Object doInTransaction(TransactionStatus status) { 
try{      } 
catch (Exception e) {
  status.setRollbackOnly(); 
}
}
}); 

简单实现

SQL:


create table `account` (
`username` varchar (99),
`salary` int (11)
);
insert into `account` (`username`, `salary`) values('小王','3000');
insert into `account` (`username`, `salary`) values('小马','3000');

注意: 通过添加/删除accountMoney() 方法中int i = 10 / 0这个语句便可验证事务管理是否配置正确。

OrdersDao.java(Dao层)

package com.gm.dao;

import org.springframework.jdbc.core.JdbcTemplate;

public class OrdersDao {
// 注入jdbcTemplate模板对象
private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} // 对数据操作的方法不包含业务操作
/**
* 小王少钱的方法
*/
public void reduceMoney() {
String sql = "update account set salary=salary-? where username=?";
jdbcTemplate.update(sql, 1000, "小王");
} /**
* 小马多钱的方法
*/
public void addMoney() {
String sql = "update account set salary=salary+? where username=?";
jdbcTemplate.update(sql, 1000, "小马");
}
}

OrdersService.java(业务逻辑层)

package com.gm.service;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import com.gm.dao.OrdersDao; public class OrdersService { private final static Logger LOG = LoggerFactory.getLogger(OrdersService.class); // 注入Dao层对象
private OrdersDao ordersDao; public void setOrdersDao(OrdersDao ordersDao) {
this.ordersDao = ordersDao;
} // 注入TransactionTemplate对象
private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
} // 调用dao的方法
// 业务逻辑,写转账业务
public void accountMoney() {
transactionTemplate.execute(new TransactionCallback<Object>() { @Override
public Object doInTransaction(TransactionStatus status) {
Object result = null;
try {
// 小马多1000
ordersDao.addMoney();
// 加入出现异常如下面int
// i=10/0(银行中可能为突然停电等。。。);结果:小马账户多了1000而小王账户没有少钱
// 解决办法是出现异常后进行事务回滚
int i = 10 / 0;// 事务管理配置后异常已经解决
// 小王 少1000
ordersDao.reduceMoney();
} catch (Exception e) {
status.setRollbackOnly();
result = false;
LOG.error("Transfer Error!,"+e.getMessage());
} return result;
}
}); }
}

TestService.java(测试方法)

package com.gm.service;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestService {
@Test
public void testAdd() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"beans.xml");
OrdersService userService = (OrdersService) context
.getBean("ordersService");
userService.accountMoney();
}
}

配置文件:

<?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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 配置c3po连接池 -->
<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:3306/mydb"></property>
<property name="user" value="root"></property>
<property name="password" value="153963"></property>
</bean>
<!-- 编程式事务管理 -->
<!-- 配置事务管理器 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务管理器模板 -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<!-- 注入真正进行事务管理的事务管理器,name必须为 transactionManager否则无法注入 -->
<property name="transactionManager" ref="dataSourceTransactionManager"></property>
</bean> <!-- 对象生成及属性注入 -->
<bean id="ordersService" class="com.gm.service.OrdersService">
<property name="ordersDao" ref="ordersDao"></property>
<!-- 注入事务管理的模板 -->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean> <bean id="ordersDao" class="com.gm.dao.OrdersDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- JDBC模板对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

log4j.properties

#Level:ERROR,WARN,INFO,DEBUG
log4j.rootLogger=ERROR, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

执行,输出

[ERROR] 2018-09-06 14:03:06,937 method:com.gm.service.OrdersService$1.doInTransaction(OrdersService.java:54)
Transfer Error!,/ by zero

扩展

首先定义了两个接口:

ServiceTemplate ---->   对TransactionTemplate进行了封装

public interface ServiceTemplate {

    /**
* <pre> 无事务模板执行业务处理
* 1. 异常捕获,及分类处理
* 2. 业务日志记录
* </pre>
*
* @param <T>
* @param clazz 返回对象
* @param action 业务操作回调的接口
* @return 服务返回对象
*/
<T> T executeWithoutTransaction(Class<? extends Result> clazz, ServiceCallback action); /**
* <pre> 支持本地事务模板执行业务处理
* 1. 本地事务封装
* 2. 异常捕获,及分类处理
* 3. 业务日志记录
* </pre>
*
* @param <T>
* @param clazz 返回对象
* @param action 业务操作回调的接口
* @return 服务返回对象
*/
<T> T execute(Class<? extends Result> clazz, ServiceCallback action); }

ServiceCallback  ---->  对TransactionCallBack进行了封装 

public interface ServiceCallback {
/**
* <pre> 校验
* 对于校验不通过,异常驱动返回
* </pre>
*/
void doLock(); /**
* <pre> 校验
* 对于校验不通过,异常驱动返回
* </pre>
*/
void check(); /**
* <pre> 执行业务逻辑
* </pre>
* @return
*/
Result executeService();
}

ServiceTemplate的具体实现ServiceTemplateImpl.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; public class ServiceTemplateImpl implements ServiceTemplate { private final static Logger LOG = LoggerFactory.getLogger(ServiceTemplateImpl.class); // 注入TransactionTemplate对象
private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
} @Override
public <T> T executeWithoutTransaction(Class<? extends Result> clazz,
ServiceCallback action) {
Result result = null;
try {
// 执行校验
action.check();
// 锁操作
action.doLock();
// 执行处理逻辑
result = action.executeService();
// 可以对结果进行初步校验TODO } catch (Exception e) {//此处可换成具体异常或子定义异常
LOG.error("Transfer Error!,"+e.getMessage());
// 打日志TODO
return (T) result; } catch (Throwable e2) {
LOG.error(e2.getMessage());
// 打日志TODO
return (T) result;
} return (T) result;
} @Override
@SuppressWarnings("unchecked")
public <T> T execute(final Class<? extends Result> clazz,
final ServiceCallback action) {
T acResult = (T) transactionTemplate.execute(new TransactionCallback() {
/**
* @see org.springframework.transaction.support.TransactionCallback#doInTransaction(org.springframework.transaction.TransactionStatus)
*/
public Object doInTransaction(TransactionStatus status) {
Result result = null;
try {
result = clazz.newInstance();
// 执行校验逻辑
action.check();
// 锁操作
action.doLock();
// 执行处理逻辑
result = action.executeService();
// 返回值异常处理
if (result == null || !(result instanceof Result)) {
throw new Exception();
}
} catch (Exception e) {//此处可换成具体异常或子定义异常
// 业务异常捕获, 回滚, 打日志TODO
LOG.error("Transfer Error!,"+e.getMessage());
status.setRollbackOnly();
return result;
} catch (Throwable e2) {
// 系统异常捕获, 回滚, 打日志TODO
LOG.error(e2.getMessage());
status.setRollbackOnly();
return result;
}
return result;
}
});
return acResult;
}
}

在业务方法中使用ServiceTemplate, 通过构建ServiceCallBack匿名内部类的方式, 传递具体的业务代码

OrdersService.java新增以下方法

public void addMoney() {
serviceTemplate.execute(Result.class, new ServiceCallback() {
@Override
public void doLock() {
// 进行锁操作
} @Override
public void check() {
// 进行校验
} @Override
public Result executeService() {
Result result = new Result();
// 具体的业务代码
// 小马多1000
ordersDao.addMoney();
// 加入出现异常如下面int
// i=10/0(银行中可能为突然停电等。。。);结果:小马账户多了1000而小王账户没有少钱
// 解决办法是出现异常后进行事务回滚
int i = 10 / 0;// 事务管理配置后异常已经解决
// 小王 少1000
ordersDao.reduceMoney();
return result;
}
});
}

修改beans.xml 

    <!-- 对象生成及属性注入 -->
<bean id="ordersService" class="com.gm.service.OrdersService">
<property name="ordersDao" ref="ordersDao"></property>
<!-- 注入事务管理的模板 -->
<property name="transactionTemplate" ref="transactionTemplate"></property>
<property name="serviceTemplate" ref="serviceTemplate"></property>
</bean> <bean id="serviceTemplate" class="com.gm.service.ServiceTemplateImpl">
<!-- 注入事务管理的模板 -->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>

修改TestService.java 

public class TestService {
@Test
public void testAdd() {
ApplicationContext context = new ClassPathXmlApplicationContext("dbBeans.xml");
OrdersService userService = (OrdersService) context.getBean("ordersService");
//userService.accountMoney();
userService.addMoney();
}
}

执行,输出

[ERROR] 2018-09-06 14:08:51,524 method:com.gm.service.ServiceTemplateImpl$1.doInTransaction(ServiceTemplateImpl.java:71)
Transfer Error!,/ by zero

注意: 如果是不需要加事务的方法, 如查询 ,那么调用serviceTemplate的executeWithoutTransaction即可

补充pom.xml

<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.test</groupId>
<artifactId>SpringTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build /> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- spring版本号 -->
<spring.version>4.1.5.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.2.6</mybatis.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<!-- 表示开发的时候引入,发布的时候不会加载此包 -->
<scope>test</scope>
</dependency>
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</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-jdbc</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-aop</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-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 导入java ee jar 包 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- 导入Mysql数据库链接jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!-- 导入dbcp的jar包,用来在applicationContext.xml中配置数据库 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<!-- JSTL标签类 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- 格式化对象,方便输出日志 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<!-- 映入JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.5</version>
</dependency> <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.4</version>
</dependency> <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.4</version>
</dependency>
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency> <dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.3</version>
<exclusions>
<exclusion>
<artifactId>httpcore</artifactId>
<groupId>org.apache.httpcomponents</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.8</version>
</dependency> <!--axis2 begin -->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-spring</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-xmlbeans</artifactId>
<version>1.6.3</version>
</dependency>
<!--axis2 end --> <dependency>
<groupId>org.kie.modules</groupId>
<artifactId>org-apache-commons-net</artifactId>
<version>6.4.0.Final</version>
<type>pom</type>
</dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-nio</artifactId>
<version>4.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-ab</artifactId>
<version>4.4.5</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency> <!-- oracle数据库驱动 -->
<dependency>
<groupId>oracle.driver</groupId>
<artifactId>oracle-driver</artifactId>
<version>11.2.0.4</version>
</dependency> <dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency> <dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency> <dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
</project>

spring 事物(二)—— 编程式事物实现与扩展的更多相关文章

  1. spring事务管理——编程式事务、声明式事务

    本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 ...

  2. Hibernate中编程式事物的简单使用

    一,openSessioin方式开启或者关闭事物 Session session = null; try { session = HibernateUtils.getSession(); sessio ...

  3. Spring框架——事务处理(编程式和声明式)

     一. 事务概述 ●在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术. ●事务就是一组由于逻辑上紧密关联而合 ...

  4. Spring(二十二):Spring 事务

    事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性. 事务就是一系列的动作,它们被当做一个单独的工作单元.这些动作要么全部完成,要么全部不起作用. 事务的是四个关键 ...

  5. vue编程式路由实现新窗口打开

    一. 标签实现新窗口打开: 官方文档中说 v-link 指令被 组件指令替代,且 不支持 target=”_blank” 属性,如果需要打开一个新窗口必须要用标签,但事实上vue2版本的 是支持 ta ...

  6. 深入理解TransactionTemplate编程式事务

    Spring可以支持编程式事务和声明式事务. Spring提供的最原始的事务管理方式是基于TransactionDefinition.PlatformTransactionManager.Transa ...

  7. Spring Aop(十二)——编程式的创建Aop代理之AspectjProxyFactory

    转发地址:https://www.iteye.com/blog/elim-2397922 编程式的创建Aop代理之AspectjProxyFactory 之前已经介绍了一款编程式的创建Aop代理的工厂 ...

  8. 二十 Spring的事务管理及其API&事务的传播行为,编程式&声明式(xml式&注解式,底层AOP),转账案例

    Spring提供两种事务方式:编程式和声明式(重点) 前者需要手写代码,后者通过配置实现. 事务的回顾: 事务:逻辑上的一组操作,组成这组事务的各个单元,要么全部成功,要么全部失败 事务的特性:ACI ...

  9. Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门

    1, 一直以来, 在用Spring进行事物管理时, 只知道用声明式的策略, 即根据不同的数据源, 配置一个事物管理器(TransactionManager), 通过配置切面(PointCut)应用到相 ...

随机推荐

  1. 金蝶KIS客户端修改IP连接服务器的方法

    问题现象:服务器IP变更后,金蝶KIS客户端打开时提示多个错误,并会自动关闭,无法联网登录 1. 到下面位置修改注册表 Windows Registry Editor Version 5.00 [HK ...

  2. 挖坑指南:iView-admin动态配置route.meta.title

    原文链接 前言 新的项目,基于iView-admin.结合自身的项目需求,对官方的模板进行一些修改.以达到动态修改route.meta,并同步更新面包屑导航文字和标签页标题. 开始 如果你还未使用过i ...

  3. 后缀自动机(SAM) 学习笔记

    最近学了SAM已经SAM的比较简单的应用,SAM确实不好理解呀,记录一下. 这里提一下后缀自动机比较重要的性质: 1,SAM的点数和边数都是O(n)级别的,但是空间开两倍. 2,SAM每个结点代表一个 ...

  4. [BJOI2006]狼抓兔子(网络流)

    题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  5. PeStudio读取pe信息

    https://blog.csdn.net/x_xx_xxx_xxxx/article/details/79867928 PeStudio  主要利用此界面工具 https://blog.csdn.n ...

  6. P.W.N. CTF - MISC - Canadian FOI

    题目 链接:https://ctftime.org/task/6935 题解 只有两个页面的网站,index.html和about.html index.html页面有一个pdf链接,指向http:/ ...

  7. 简单说下cookie,LocalStorage与SessionStorage.md

    最近在网上看到有人讨论这三个的一些概念与区别,发现自己也一直没有较好的总结,所以查阅了一些资料来阐述一下. 基本概念 cookie cookie英文意思是小甜饼,是原来的网景公司创造,目前是在客户端存 ...

  8. spring cloud学习笔记五 网关服务zuul

    网关服务是指,客户端发送的请求不用直接访问特定的微服务接口,而且是经过网关服务的接口进行交互,网关服务再去到特定的微服务中进行调用.   网关服务的路由功能和Nginx的反向代理一样,所有的服务都先会 ...

  9. CentOS7安装配置redis5.0.5

    一.安装必需包gcc yum install gcc 二.下载redis,并解压 wget http://download.redis.io/releases/redis-5.0.5.tar.gz t ...

  10. Java序列化及反序列化

    序列化概念: 1.Java序列化与反序列化  Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道 ...