12220171030
package com.tiger.service;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* 方式 一:编程式事务
* @author tiger
* @date 2017年10月30日
*/
@Component
public class CountService1 {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private DataSourceTransactionManager txManager;
/**
* 对转账操作进行事务管理
* @param method
* @throws SQLException
*/
public void log1() throws SQLException {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
//设置隔离级别
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
TransactionStatus ts = txManager.getTransaction(definition);
try {
String getsql = "update ts set count=count+100 where name = 'A'";
jdbcTemplate.update(getsql);
//人工制造异常测试
// int a = 100/0;
String updatesql = "update ts set count=count-100 where name = 'B'";
jdbcTemplate.update(updatesql);
//提交事务
txManager.commit(ts);
}catch (Exception e) {
System.err.println("发生异常,数据回滚 "+e.getMessage());
txManager.rollback(ts);
}
}
}
package com.tiger.main;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tiger.service.CountService1;
import com.tiger.service.CountService2_3_4;
/**
* 测试
* @author tiger
* @date 2017年10月25日
*/
public class Mian {
public static void main(String[] args) throws SQLException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
// test1(ctx);
// test2(ctx);
test3_4(ctx);
}
/**
* 方式一
* @throws SQLException
*/
public static void test1(ApplicationContext ctx) throws SQLException {
CountService1 logService = (CountService1) ctx.getBean("countService1");
logService.log1();
}
/**
* 方式二:注意,必须把方式三xml配置给注释掉
* @throws SQLException
*/
public static void test2(ApplicationContext ctx) throws SQLException {
CountService2_3_4 logService = (CountService2_3_4) ctx.getBean("countTransactionProxy");
logService.log2_3_4();
}
/**
* 方式三(AOP) & 方式四(注解)
* @throws SQLException
*/
public static void test3_4(ApplicationContext ctx) throws SQLException {
CountService2_3_4 logService = (CountService2_3_4) ctx.getBean("countService2_3_4");
logService.log2_3_4();
}
}package com.tiger.service;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.*;
/**
* 方式二 & 方式 三 & 方式 四:声明式事务,配置beans.xml文件
* @author tiger
* @date 2017年10月30日
*/
@Component
public class CountService2_3_4 {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 对转账操作进行事务管理
* @param method
* @throws SQLException
*/
// @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
public void log2_3_4() throws SQLException {
String getsql = "update ts set count=count+100 where name = 'A'";
jdbcTemplate.update(getsql);
//人工制造异常测试
int a = 100/0;
String updatesql = "update ts set count=count-100 where name = 'B'";
jdbcTemplate.update(updatesql);
}
}
PROPAGATION_REQUIRED,ISOLATION_DEFAULT
#Let's talk about this file in src catalog
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=utf8&useSSL=true
jdbc.username=root
jdbc.password=123456
#SET FOREIGN_KEY_CHECKS=0;
#
#-- ----------------------------
#-- Table structure for ts
#-- ----------------------------
#DROP TABLE IF EXISTS `ts`;
#CREATE TABLE `ts` (
# `name` varchar(20) DEFAULT NULL,
# `count` int(11) DEFAULT NULL
#) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#
#-- ----------------------------
#-- Records of ts
#-- ----------------------------
#INSERT INTO `ts` VALUES ('A', '1400');
#INSERT INTO `ts` VALUES ('B', '600');package com.tiger.bean;
import org.springframework.stereotype.Component;
@Component
public class Count {
private String name;
private Integer count;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Count(String name, Integer count) {
super();
this.name = name;
this.count = count;
}
public Count() {
super();
}
@Override
public String toString() {
return "Log [name=" + name + ", count=" + count + "]";
}
}
12220171030
1、事务的概念:一组逻辑执行单元(多条sql语句),要么全部执行成功,要么失败。
2、作用:保证数据的完整性,因为很多复杂的事物要分步进行,但它们组成了一个整体,要么整体生效,要么整体失效。这种思想反映到数据库上,就是多条SQL语句,要么所有执行成功,要么所有执行失败。
3、事务四个特征:
1)、原子性(Atomicity):表示组成一个事务的多个数据库操作是一个不可分割的原子单元
2)、一致性(Consistency):事务操作成功后,数据库存所处的状态和它的业务规则是一致的,即数据不会被破坏
3)、隔离性(Isolation):在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确地说,并非要做到完全无干扰程度,隔离级别越高,数据一致性越好,但并发性越弱
4)、持久性(Durability):一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中。即使在提交事务后,数据库马上崩溃,在数据库重启时,也必须保证能够通过某种机制恢复数据
4、隔离性:解决数据并发的问题
5、并发现象:
1)、脏读【数据破坏】
2)、不可重复读【数据完好,两次读取的数据不同,第二次比第一次少,第二次读取的数据才是真实数据】
3)、幻象读【数据完好,两次读取的数据不同,第二次比第一次多,第二次读取的数据才是真实数据】
4)、第一类丢失更新【数据破坏,数据变少】
5)、第二类丢失更新【数据破坏,数据变多】
5、隔离级别
1)、读未提交数据(READ UNCOMMITED):避免第一类丢失更新
2)、读已提交数据(READ COMMITED):避免脏读、第一类丢失更新的发生(默认[isolation=Isolation.DEFAULT])
3)、读可重复数据(REPEATABLE READ):只允许幻象
4)、串行读取数据(SERIALIZABLE):隔离最佳,并发性能差。
6、Spring如何管理事务:亮点 --> 声明式事务管理,不需要硬编码,只需在xml配置文件中描述事务如何操作,最终交由底层封装好的工具类完成。
7、Spring管理事务核心API:
1)、TransactionDefinition:描述事务的属性
(1)、隔离级别
(2)、传播行为(事务中包含另外一个事务,默认沿用之前的事务[注解写法:propagation=Propagation.REQUIRED])
REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务
NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
(3)、设置事务只读
2)、PlatformTransactionManager:管理事务
(1)、创建事务
(2)、提交事务
(3)、事务的回滚
3)、TransactionStatus:描述事务状态
(1)、描述事务状态
(2)、获取当前事务是不是一个新事务
(3)、获取当前事务是否只读
8、Spring管理事务的 4 种编写方式:
1)、编程式实现事务管理
2)、基于TransactionProxy的声明式事务管理
3)、基于 命名空间的声明式事务管理
4)、基于 @Transactional 的声明式事务管理
#must import jar log4j-1.2.17.jar
log4j.rootLogger=DEBUG,R,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=d:/pimc_log4j.log
log4j.appender.R.MaxFileSize=1000KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n