标签:atom 封装 外壳 数据不一致 账户 mil 对象 回滚 用户
一,什么是事务?
数据库事务是指由一个或多个SQL语句组成的工作单元,这个工作单元中的SQL语句相互依赖,如果有一个SQL语句执行失败,就必须撤销整个工作单元。
在并发环境中,多个事务同时访问相同的数据资源时,可能会造成各种并发问题,可通过设定数据库的事务隔离级别来避免,还可采用悲观锁和乐观锁来解决丢失更新这一并发问题。
二,事务的特性
A: Atomic原子性,整个事务不可分割,要么都成功,要么都撤销。
C: Consistency一致性,事务不能破坏关系数据的完整性和业务逻辑的一致性,例如转账,应保证事务结束后两个账户的存款总额不变。
I: Isolation隔离性,多个事务同时操纵相同数据时,每个事务都有各自的完整数据空间
D: Durability持久性,只要事务成功结束,对数据库的更新就必须永久保存下来,即使系统发生崩溃,重启数据库后,数据库还能恢复到事务成功结束时的状态。
三,多事务并发问题
1,第一类丢失更新:在撤销事务时,把其他事务提交的更新数据覆盖;
2,脏读:一个事务读到另一个事务未提交的的更新数据(A事务访问到B事务更新后的数据后,B事务突然回滚)
3,不可重复读:一个事务在另一个事务更新前后访问数据,导致重复读取数据不一致
4,第二类丢失更新:一个事务覆盖另一个事务已提交的更新数据;
5,幻读:一个事务在另一个事务插入数据前后访问记录数,导致前后不一致。
四,如何解决并发问题:
通过设置事务隔离
hibernate是JDBC的轻量级封装,本身不具有事务管理能力,hibernate将其委托与底层的JDBC或者JTA,hibernate只是将底层的JDBCTransation或者JTATransation进行封装了一下,在外边套上Transation和Session的外壳,实现事务的管理和调度功能。
当Hibernate中的SessionFactory获取Session时,hibernate会为当前的Session初始化对应的Connection对象,调用Connection的setAutoCommit()方法将自动事务提交设置为False。
为避免事务并发引起的问题,可以在hibernate中配置文件中设置事务隔离级别
<property name="connection.isolation">2</property>
隔离级别越高,事务并发问题就越少,但是事务并发性能越低,建议选择READ_COMMITED
READ_COMMITED级别可以避免脏读,但无法避免不可重复读和幻读,那么对于要求隔离级别高的数据,可以通过应用程序使用乐观锁和悲观锁解决
五,悲观锁和乐观锁
悲观锁是通过数据库本身实现的,使用悲观锁的数据,其他任何用户都不能访问了
在hibernate调用数据库悲观锁:
调用session的get 或 load方法;
调用session的lock方法;
调用Query的setLockMode方法;
以上三种将锁模式指定为LockOption.UPGRADE
乐观锁使用应用程序的版本控制,由程序的逻辑实现的。
特点:既能保证多个事务并发访问数据,又能防止第二类丢失更新
hibernate的乐观锁可以通过两种方式实现:版本控制,时间戳。
版本控制:在实体类中添加version成员变量;
在映射配置文件中添加<version>元素映射版本属性;
当hibernate初始插入一条更新语句时,会自动将版本字段version进行初始化;
当更新某个实体对象时,hibernate会根据对象的id和version属性匹配更新的数据库数据;
如果存在匹配的记录,那么更新该记录,version列值+1;
如果不存在匹配的记录,那么hibernate抛出过期对象状态异常----StaleObjectStateException
标签:atom 封装 外壳 数据不一致 账户 mil 对象 回滚 用户
原文地址:http://www.cnblogs.com/sixianyishengruliebo/p/7044906.html