“数据库标志位已经自增,因此无法回滚” 以oracle数据库为例、hibernate的native对应数据库的sequence自增序列、这个序列是无须回滚的。 在数据库有一张最大号表、你可以想象每个有自增字段的表都有一张最大号表、表中只有一个number字段就是当前最大号。 这个最大号只要保证按序递增不会重复即可,出现“跳号”不是问题,因为它本身就是与业务无关的。不要老想着事务回滚也得回滚它。 session.save(event)以后hibernate已经向数据库发出sql、索取到了主键并保存了event,这时event已经存入了数据库,但是由于处于事务当中、所以你从数据库是否能看到event还要看数据库本身的隔离级别:未提交可读能查到——这就是所谓脏读、提交后可读及以上级别查不到。数据库隔离级别(并发): 是否存在脏读 是否存在不可重复读 是否存在幻读 1、read uncommitted 未提交可读 —— 基本不会这么用 y y y 2、read commited 提交后可读 —— oracle等大多DB的默认 n y y 3、repeatable read 可重复读 —— mysql默认 n n(悲观锁) y 4、serilizable 序列化读 —— 序列化无并发 n n n 脏读:没提交的数据也会读到 不可重复读:一个人在读的时候另一个人修改之、前者再读结果会变化、一个读结果不保证下次重复出现 幻读:一个人读出5条数据、另一人又添加了5条、前者再读会变为十条即所谓幻读(类似不可重复读、但是指的是插入、要解决得加表级锁)序列化读:无并发、所有访问排队逐个进行、性能极差、基本也不会用。 悲观锁: 读的时候加行级锁、不让别人改。可避免不可重复读但是依然不能避免幻读
如果没有这一句的话,
那么就是还没有真正的保存到数据库表中。
以oracle数据库为例、hibernate的native对应数据库的sequence自增序列、这个序列是无须回滚的。
在数据库有一张最大号表、你可以想象每个有自增字段的表都有一张最大号表、表中只有一个number字段就是当前最大号。
这个最大号只要保证按序递增不会重复即可,出现“跳号”不是问题,因为它本身就是与业务无关的。不要老想着事务回滚也得回滚它。
session.save(event)以后hibernate已经向数据库发出sql、索取到了主键并保存了event,这时event已经存入了数据库,但是由于处于事务当中、所以你从数据库是否能看到event还要看数据库本身的隔离级别:未提交可读能查到——这就是所谓脏读、提交后可读及以上级别查不到。数据库隔离级别(并发): 是否存在脏读 是否存在不可重复读 是否存在幻读
1、read uncommitted 未提交可读 —— 基本不会这么用 y y y
2、read commited 提交后可读 —— oracle等大多DB的默认 n y y
3、repeatable read 可重复读 —— mysql默认 n n(悲观锁) y
4、serilizable 序列化读 —— 序列化无并发 n n n
脏读:没提交的数据也会读到
不可重复读:一个人在读的时候另一个人修改之、前者再读结果会变化、一个读结果不保证下次重复出现
幻读:一个人读出5条数据、另一人又添加了5条、前者再读会变为十条即所谓幻读(类似不可重复读、但是指的是插入、要解决得加表级锁)序列化读:无并发、所有访问排队逐个进行、性能极差、基本也不会用。
悲观锁: 读的时候加行级锁、不让别人改。可避免不可重复读但是依然不能避免幻读