事务指逻辑上对数据库的一组操作,事务有以下四大特性:
1.原子性:事务的一组操作捆绑在一起,要么全都执行,要么都不执行
2.一致性:事务的完成使数据库从一致性状态转到一致性状态,一致性也就是指数据的正确性或者稳定的一种状态,例如A给B转账的操作中,A的余额减少但B的余额还未增多的时刻,此时数据库就没有处于一致性的状态
3.隔离性:多个并发事务之间要相互隔离,不能产生干扰
4.持久性:事务一旦被提交,数据库就会同步更新,它带来的影响就是永久性的
事务命令
1.开启事务:start transaction
2.事务回滚:rollback
3.提交事务:commit
在start transaction和commit之间的操作属于一个事务,在提交之前,如果发生了异常,数据库会自动回滚,也可以手动rollback
JDBC使用事务
1.开启事务:Connection.setAutoCommit(false);
2.事务回滚:Connection.rollback();
3.提交事务:Connection.commit();
注意有时我们不需要回滚整个事务,而是回滚部分事务,所以要设置事务回滚点:
操作1...
Savepoint sp = conn.setSavepoint();
操作2...
Conn.rollback(sp);
Conn.commit(); // 回滚后必须通知数据库提交事务
其中操作2会被回滚掉,操作1会保存下来然后被提交
事务的隔离级别
首先如果不隔离,会出现以下三种情况:
1.脏读:你读取到了其他事务已经修改但还未提交的数据(注意虽然未提交但数据库中的记录也是会改变的,只是提交之后这种操作就被完全持久化,无法通过回滚来消除)
2.不可重复读:在一个事务中,你前后两次读到的同一个数据的值不同,因为有其他事务对其进行了修改
3.幻读:在一个事务中,你对某一批数据整体进行了操作,但由于在这批数据之外有其他事务修改了数据,也可能会造成操作结果的不合理,例如你在将所有数据的状态更新为1的同时,其他事务插入了一条状态为0的数据,最后你看到的结果并不是所有数据状态都为1
加锁策略:
1.避免脏读:修改数据时加排它锁,事务提交之后释放锁
2.避免不可重复读:读数据时加共享锁,事务提交之后释放锁,当所有共享锁都释放时才可进行数据的修改
3.避免幻读:加范围锁,它是共享锁,整张表都不允许修改数据
MySQL有四种隔离级别可设置:
1.Serializable(串行化):可避免脏读、不可重复读、幻读情况的发生
2.Repeatable Read(可重复读):可避免脏读、不可重复读情况的发生
3.Read Committed(读已提交):可避免脏读情况发生
4.Read Uncommitted(读未提交):最低级别,以上情况均无法保证
MySQL默认隔离级别为Repeatable Read
设置方法:
1.全局设置
修改my.ini文件
可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = REPEATABLE-READ
2.登录mysql后对当前session进行修改
set session transaction isolation level read uncommitted; // 设置当前事务隔离级别