事务管理
一、概述
1.1 事务概念
1、概念:事务一般特指数据库事务,是指作为一个程序执行单元执行的一系列操作,要么完全执行,要么完全不执行。
2、事务的特性:
①原子性(atomicity):一个事务是一个不可分割的工作单位
②一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态
③隔离性(isolation):一个事务的执行不能被其他事物干扰
④持久性(durability):一个事务一旦提交,他对数据库中数据的改变应该是永久性的
二、MySQL事务处理
1.1 基本语句
MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务。
MySQL默认以自动提交(autocommit)模式运行。
语句:
- BEGIN(STARTTRANSACTION) 显式地开启一个事务
- COMMIT 提交事务,并使用对数据库进行的所有修改变为永久性的
- ROLLBACK 回滚事务,并撤销正在进行的所有未提交的修改
1.2 并发问题
1.2.1 脏读
脏读:读取了脏数据,即读取了不合理的、错误的或者本来不存在的数据;
解决方法:通过限制只能读取永久性的数据
脏读:读取数据库中永久的数据
1.2.2 不可重复读
不可重复读:在事务执行的过程中重复读取的同一项数据,但是读取到的结果是不一样的(由于事务B修改对事务A造成了影响)
解决办法:通过锁行解决
不可重复读:锁行
1.2.3 幻读
**幻读:**由于事务B插入对事务A造成了影响(如事务A将所有商品的库存量改为0,交叉执行的事务B又插入了库存为100的新商品,此时事务A再次查询修改结果发现仍有一个库存量为100的商品)
**解决办法:**通过锁表解决
幻读:锁表
1.3 事务隔离级别
MySQL事务隔离级别(从上到下执行效率越来越低,隔离级别越来越高)
- 读未提交(read - uncommitted) 不能解决脏读、不可重复读、幻读等问题
- 读已提交(read - commited)解决了脏读问题,不能解决不可重复读和幻读等问题
- 可重复读(repetable-read)解决了脏读和不可重复读的问题,没有解决幻读的问题
- 串行化(serializable)解决了脏读、不可重复读、和幻读的问题
语句
- select @@tx_isolation 查询默认隔离级别
- set session transaction isolation level xxx 设置当前会话隔离级别
三、JDBC事务处理
1.1 基本语句
JDBC事务处理:
- Connection接口是JDBC进行事务处理的核心,必须是基于一个Connection对象的多个sql操作才能封装成一个事务,不同的Connection对象没办法封装成一个事务;
- JDBC默认事务处理行为是自动提交;
事务相关方法:
- setAutoCommit 设置自动提交;
- rollback 回滚事务;
- commit 提交事务;
public class OrderTest {
private String driver = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3307/os?useUnicode=true&characterEncoding=utf8";
private String userName = "root";
private String password = "root";
@Test
public void addOrder(){
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection = null;
try {
connection = DriverManager.getConnection(url,userName,password);
connection.setAutoCommit(false);
Statement statement = connection.createStatement();
statement.execute("insert into orders values('100002','100001',2,2499,now(),null,null,'刘备','1330000000','成都','待发货')");
statement.execute("update products set stck=stock-2 where id='100001'");
statement.close(