事务:一件事情可能有多个单元组成,要求这些单元要么全成功,要么全失败。
事务的操作:
在mysql 下操作:
方式一: start transaction 开启事务
rollback 事务回滚
commit 事务提交
方式二:
show variables like ‘%commit%’;
查看当前autocommit值,在mysql数据库中它的默认值为ON, 代表自动事务。 意思就是执行任意一条sql语句都会自动提交事务。
2.jdbc 下操作事务
java.sql.Connection 接口中有几个方法是用于可以操作事务
1> setAutocommit(boolean flag)
如果flag=false; 相当于start transaction
事务的特性 ACID
- 原子性(Atomicity): 不能再分,都成功或者都失败
- 一致性(Consistency): 事务执行完成,数据保持前后一致。
- 隔离性(Isolation): 事务和事务之间不能相互影响。
- 持久性(Durability): 一旦被提交,数据库中的数据永久被改变。
不考虑事务隔离,出现的问题:
- 脏读: 一个事务读取到另一个事务的未提交数据。
- 不可重复读: 两次读取的数据不一致。(update)
- 虚读(幻读): 两次读取的数据不一致。(insert)
- 丢失更新:两个事务对同一条记录进行操作,后提交的事务将先提交事务的修改覆盖了
对于以上问题可以设置事务的隔离级别来解决
事务的隔离级别(4 种)
Serializable (串行化): 可避免脏读,不可重复读,虚读情况的发生
Repeatable read: 可避免脏读,不可重复读情况的发生
Read committed: 可避免脏读情况的发生
Read uncommitted: 最低级别,以上情况均无法保证。
怎么设置事务的隔离级别
mysql 种设置
1.查看隔离级别
select @@tx_isolation 查询当前事务隔离级别
mysql 种默认的事务隔离级别是 Repeatable readmysql中设置隔离级别
set session transaction isolation level 隔离事务级别
jdbc中设置
在jdbc中设置事务隔离级别使用java.sql.Connection 接口中提供的方法
void setTransactionIsolation(int level) throws SQLException
参数level 可以取一下值 static int TRANSACTION_READ_COMMITTED 指示不可以发生脏读的常量;不可重复读和虚读可以发生。
static int TRANSACTION_READ_UNCOMMITTED
指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。
static int TRANSACTION_REPEATABLE_READ
指示不可以发生脏读和不可重复读的常量;虚读可以发生。
static int TRANSACTION_SERIALIZABLE
指示不可以发生脏读、不可重复读和虚读的常量。
解决丢失更新
1.悲观锁
假设丢失更新一定会发生---利用数据库内部锁机制,管理事务
1. 共享锁
select * from table lock in share mode
2. 排它锁
select * from table for update
update 语句默认添加排它锁
乐观锁
假设丢失更新不会发生---利用程序中添加版本字段解决丢失更新问题。
连接池
创建一个容器,用于装入多个Connection对象,
在使用连接对象时,从容器中获取一个Connection,
使用完之后,在将这个Connection 重新载入到容器中。
这个容器就是连接池。(DataSource) 也叫数据源。
dbcp 是apache 的开源连接池
c3p0 配置文件 c3p0.properties 或者c3p0-config.xml 放倒classpath 下面,会自动查找。