我也是个初学者,我是这样理解的:session.save(event);执行的后已经往数据库中插入了数据,顾主键自增了。但是由于你没有commit,所以你在数据库端查询的时候查不到,是因为在插入数据时有加锁的机制,这里应该是避免幻影读吧,只有commit完毕才能查看到数据。  

解决方案 »

  1.   

    tx.commit()是把所做的事物提交到数据库中,
    如果没有这一句的话,
    那么就是还没有真正的保存到数据库表中。
      

  2.   

    没有事务提交的话...数据在session缓存中事务提交了,就插入到数据库中了
      

  3.   

    “数据库标志位已经自增,因此无法回滚”
    以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条、前者再读会变为十条即所谓幻读(类似不可重复读、但是指的是插入、要解决得加表级锁)序列化读:无并发、所有访问排队逐个进行、性能极差、基本也不会用。
    悲观锁:  读的时候加行级锁、不让别人改。可避免不可重复读但是依然不能避免幻读