一,什么是数据库事务?
简单来说,数据库事务(简称事务),是指一组数据操作,表现为一组SQL语句。要么全部执行成功,要么全部失败。
二, 为什么需要事务?
- 是为了从失败中恢复
- 是为了隔离并发操作造成的数据混乱。
脏读(dirty read):一个事务读取了另一个事务尚未提交的数据,
不可重复读(non-repeatable read) :一个事务的操作导致另一个事务前后两次读取到不同的数据
幻读(phantom read) :一个事务的操作导致另一个事务前后两次查询的结果数据量不同。
三, 事务有哪些特点?
说到数据库事务就不得不说,数据库事务中的四大特性,ACID:
- 原子性(Atomic) 对数据的修改要么全部执行,要么全部不执行。
- 一致性(Consistent) 在事务执行前后,数据状态保持一致性。
- 隔离性(Isolated) 一个事务的处理不能影响另一个事务的处理。
- 持续性(Durable) 事务处理结束,其效果在数据库中持久化。
四,如何实现事务?
- SQL
既然事务是一组SQL语句,自然能用SQL实现,只不过项目一般都采用特定语言的API,例如:JDBC。不直接使用SQL语句。
以Mysql 转账为例:
1有800块
2有200块
执行事务
START TRANSACTION READ WRITE;
BEGIN WORK;
update deposit set `money` = `money` - 100 where id = 1;
update deposit set `money` = `money` + 100 where id = 2;
image.png上面的
READ WRITE
是Mysql 的事务描述符,很少使用,和事务隔离差不多
WORK
是别名
#COMMIT WORK;
ROLLBACK WORK;
我们再提交事务,这个结果就会存储到数据库,如果我们回滚事务,又会回到操作前的状态。
Mysql 事务的完整语法 https://dev.mysql.com/doc/refman/8.0/en/commit.html
- JDBC 事务
JDBC中的 Connection的三个方法与事务有关:
setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值为true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置为false,那么相当于开启了事务了;con.setAutoCommit(false) 表示开启事务。
commit():提交结束事务。
rollback():回滚结束事务。
JDBC处理事务的代码格式:
try{
con.setAutoCommit(false);//开启事务
......
con.commit();//try的最后提交事务
} catch() {
con.rollback();//回滚事务
}
五,事务的隔离级别
隔离级别 | 出现的并发问题 | 性能 |
---|---|---|
READ UNCOMMITTED(读未提交数据) | 脏读,不可重复读,幻读(虚读) | 最高 |
READ COMMITTED(读已提交数据)(Oracle) | 不可重复读,幻读(虚读) | 高 |
REPEATABLE READ(可重复读)(MySQL) | 幻读(虚读) | 中 |
SERIALIZABLE(串行化) | 无 | 低 |
- Mysql 设置隔离级别
SET [GLOBAL | SESSION] TRANSACTION
transaction_characteristic [, transaction_characteristic] ...
transaction_characteristic: {
ISOLATION LEVEL level
| access_mode
}
level: {
REPEATABLE READ
| READ COMMITTED
| READ UNCOMMITTED
| SERIALIZABLE
}
access_mode: {
READ WRITE
| READ ONLY
}
- JDBC设置隔离级别
con.setTransactionIsolation(int level) :参数可选值如下:
Connection.TRANSACTION_READ_UNCOMMITTED;
Connection.TRANSACTION_READ_COMMITTED;
Connection.TRANSACTION_REPEATABLE_READ;
Connection.TRANSACTION_READ_SERIALIZABLE。
网友评论