1、sql中的事务:就是在一个业务处理逻辑中对所有操作。
2、特点:一个事务中如果有一个数据库操作失败,那么整个事务的所有数据库操作都会失败,数据库数据就会回滚到该事务开始之前的状态。
3、特性:acid
原子性:事务中的所有数据库操作是一个整体,是不可分割的,不会只是执行某一段数据库操作。
一致性:在同一个时间点的所有事务读取的信息一致。
隔离性:事务之间是隔离的,多个事务访问同一个数据时不会对其他事务产生影响。
持久性:当一个事务执行完毕时,它对数据的影响会保存到数据库中。
4、关系型数据库保持事务的特性:
原子性、一致性、持久性通过数据库日志实现
隔离性通过数据库中的锁机制实现的,在sql开发中为了便于开发人员使用数据库锁,sql表中定义
了数据库的隔离级别,为数据库设置不同的隔离级别,就可以调用不同的数据库锁。
5、事务的并发
多个事务同时执行叫做事务的并发。
6、同一个数据的事务并发会引起的问题:
1、第一类丢失更新:一个事务把另外一个事务提交的数据回滚,造成第二一个事务执行结果失效
2、脏读:一个事务读取另外一个事务提交之前的数据,
脏读和第一丢失更新对数据一致性造成很严重的问题,所以应该尽量避免这两类问题
3、不可重复读:一个事务读到另一事务提交之后的更新数据
4、第二类丢失更新:与‘第一类丢失更新’不同的是第二类更新丢失是由于一个事务在执行工程中
有另外一个事务在第一个事务‘开启之后开启’-‘结束之前结束’,导致第一个事务执行
完成时时依照第二个事务执行前的数据进行修改的,导致第二个事务执行结果无效
5、幻读:当第一个事务读取全部数据的时候第二个事务又添加了一条数据,导致第一个事务读取的
还是第二个事务执行之前的数据
7、避免事务并发引起的问题
1、使用数据库隔离级别,数据库隔离有4种
1、read uncommitted 读未提交 避免第一类丢失更新,但是无法避免脏读、不可重复读、
幻读
2、read committed 读已提交 可以避免第一类丢失更新、脏读、但是不能避免不可重复读、
幻读
3、repeatable 可重复 可以避免第一类丢失更新、脏读、不可重复读、但是不能避免幻读
4、serializable 串行化 可以避免所有并发引起问题
由于数据库的隔离级别越高会导致其事务并发性能越差,所以一般情况并不会设置最高的隔
离级别,一般只会隔离严重的并发问题(如使用read committed),当项目要求并
发要求更高的时候才会使用更高的隔离级别
在hibernate中可以使用配置文件制定
1 | 2 | 4 | 8
2、使用锁来避免事务并发引起的问题
在hibernate中可以使用悲观锁和乐观锁
悲观锁:
session.get(类名.class,id,lockoptions.upgrade);
session.load(类名.class,id,lockoptions.upgrade);
session.createquery(“hql语句”).setlockoptions(lockoptions.upgrade);
session.createcriteria(类名.class).setlockmode(lockmode.upgrade);
当一个数据获取悲观锁的时候,其他事务就不能访问这个数据,只有当该事
务释放的时候其他事务才能对这个数据进行操作,需要数据库支持
select xx from xxx for update。
悲观锁的缺陷:当事务过长时会影响其他事务对数据的操作,影响整个项目
的运行,严重的可能会导致死锁,
乐观锁:乐观锁是基于在数据库表中新增一列数据用来标记,当进行数据操作的时候
匹配当前标记数据与之前的查询到的标记数据是否一致,如果不一致则不执
行数据库操作
在hibernate中需要在数据库中添加一列 version 用来保存标记,数据类型
int ,并在实体类映射文件中配置
放在id配置属性后面普通配置属性前面
映射属性进行映射后才能使用,配置完成后再每次操作数据库的时
候都会在sql语句后面添加 version = ?条件进行判断