hibernate事物配置
connection.autocommit=true
这个属性是说,如果是true的话,就是自动提交,比如
在一个业务中中,你有多个操作数据库的子业务,
例如
业务SuperA中有子业务suba,subb,subc.....
如果是自动的话,
suba操作成功 提交
subb操作失败 回滚
subc操作失败 回滚
按照我们的逻辑当SuperA中有某一环节操作失败的话,都应该回滚到没有操作之前
而当为true时,则为出现a成功 b,c失败 ,SuperA不具备了时务的特征,原子性等等
当不是true时,这时事务的管理提交给了spring,Spring的事务控制是以一个bean为单位的,
SuperA是bean中一个方法或者其他,这样当执行事务SuperA时,只要a,b,c...中一个失败,都
会认定是失败操作 roolback. 这样避免了脏数据的出现,也合乎了事务的特征。
1,和缓存没关系,当整合spring时,ORM一般都是hinernate,缓存级别都是在hibernate的xml文件中设置的,一级缓存session,2级缓存sessionFactory,如果不是用orm,纯JDBC的话,缓存级别只能在数据库端设置。所以与connection.autocommit= true无关。
(一)如果默认为true
1.保存对象是不需要开事务的,读写随意.
2.session.flush()是有意义的,因为session.flush()的操作是可以生效的.
(二)如果默认值为false
1.保存对象必须使用事务,不管是声明式事务还是编程式事务.当然也可以采用重置autocommit的方式
2.session.flush()是在事务块里面是没有意义的,因为数据操作是要统一提交的,但是这里我并没用经过复杂的测试,稍后有时间我再尝试几种情况.
3.如果不在事务块内修改持久化对象后执行session.flush(),数据库会锁表.
总结:
session的autocommit模式也是可以修改的,所以默认为false,在复杂的情况下需要手工控制flush时可以修改autocommit
疑惑:
查阅了spring的源码,在使用spring的声明式事务时,会修改session的FlushMode为AUTO,很不解,查阅JDBCTransaction类的commit方法
1
2
3
|
if
( !transactionContext.isFlushModeNever() && callback ) {
transactionContext.managedFlush();
//if an exception occurs during flush, user must call rollback()
}
|
实际上当FlushMode为MANUAL或NEVER时,提交的时候会通过managedFlush()遍历所有的session的flush方法,不知道在事务块里面spring为什么要修改FlushMode为AUTO,当事务结束时又会改回原有的mode.
楼下可以继续讨论.
如果你save了对象,那么hibernate并没有把数据存入数据库,这时这个对象存在内存中,这时你如果使用get或者load方法取这个对象,你可以取到,也许你会误认为,这个对象存在数据库中,其实它还在内存中,hibernate回在合适的时候(一般是内存中的临时对象和持久化对象达到一定容量)把内存中的持久化对象同步到数据库中。如果你想强行把内存中的数据同步到数据库中,可以使用那个session的flush方法。
hibernate事务是依赖与数据库事务的(这句话意思是,只有数据库支持事物的,配置的事物才能生效),
调用save方法后SQL语句已经发送到数据库,所以提交到数据库很正常,如果你应用了事务但是autocommit为false才不会保存到数据库,前提是你的表是InnoDB(支持事务),如果是MyISAM(不支持事务)的话不管你是否应用了事务只要调用save方法数据库中都会存入记录
如果你save了对象,那么hibernate并没有把数据存入数据库,这时这个对象存在内存中,这时你如果使用get或者load方法取这个对象,你可以取到,也许你会误认为,这个对象存在数据库中,其实它还在内存中,hibernate回在合适的时候(一般是内存中的临时对象和持久化对象达到一定容量)把内存中的持久化对象同步到数据库中。如果你想强行把内存中的数据同步到数据库中,可以使用那个session的flush方法。