. 锁
业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算处理中,希望对某个结算时间点的数据进行处理,而不希望在结算过程中(可能是几秒,也可能是几个小时),数据再发生变化。此时,需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,就是所谓的“锁”,即给选定的目标数据上锁,使其无法被其他程序修改。
Hibernate支持两种锁机制,悲观锁(Pessimistic Locking)和乐观锁(OptimisticLocking)。
悲观锁是指对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有一个客户也正在存取同一笔数据。为了保持数据被操作的移植性,于是对数据采取了数据库层次的锁定状态。依靠数据库提供的锁机制来实现。
乐观锁则乐观地认为数据很少发生同时存取的问题,因而不做数据库层次上的锁定。为了维护正确的数据,乐观锁采用应用程序上的逻辑实现版本控制的方法。
Hibernate中通过版本号检索来实现后更新为主,这也是Hibernate推荐的方式。在数据库中假如有一个Version栏记录,在读取数据时连带版本号一同读取,并在更新数据时递增版本号,然后对版本与数据库中的版本号,如果大于数据库中的版本号,则给予更新,否则就报错误。
比如,有两个客户端,A客户先读取了账户余额200元,之后B客户也读取了账户余额200元的数据。在并发情况下,A客户提取了100元,对数据库做了变更,此时数据中的数据余额为100元,B客户也要提取80元,根据所取得的资料,200-80将为120,再对数据库进行变更,最后的余额就会不正确。
实现了乐观锁,A客户读取账户余额200元,并连带读取版本号为5的话,B客户此时也读取帐号余额为200元,版本号也为5。A客户在领款后帐号余额为100,此时将版本号变为6,而数据库中版本号为5。所以准予更新,更新数据库后,数据库的余额为100,版本号为6。B客户领款后要变更数据库,其版本号为5,但是数据库的版本号为6,此时不予更新。如果B客户试图更新数据,将会引发异常。也可以捕捉这个异常,在处理数据中重新读取数据库中的数据。