Hibernate中并发策略的乐观锁理解和编程实现

来源:互联网 发布:华中数控车床仿真软件 编辑:程序博客网 时间:2024/05/17 22:28

1:实体类代码

  

package com.cn.edu;public class Account {private long id;private int version;private String accountId;private String accountName;private float balance;public long getId() {return id;}public void setId(long id) {this.id = id;}public int getVersion() {return version;}public void setVersion(int version) {this.version = version;}public String getAccountId() {return accountId;}public void setAccountId(String accountId) {this.accountId = accountId;}public String getAccountName() {return accountName;}public void setAccountName(String accountName) {this.accountName = accountName;}public float getBalance() {return balance;}public void setBalance(float balance) {this.balance = balance;}}

映射文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><hibernate-mapping>    <class name="com.cn.edu.Account" table="accounts" optimistic-lock="version">        <id name="id" type="java.lang.Long">            <column name="id"/>            <generator class="native" />        </id>        <version name="version" column="version" type="java.lang.Integer" />        <property name="accountId" type="java.lang.String">             <column name="account_id" length="32"/>        </property>        <property name="accountName" type="java.lang.String">             <column name="account_name" length="30"/>        </property>        <property name="balance" type="java.lang.Float">             <column name="balance" sql-type="float"/>        </property>    </class></hibernate-mapping>

2:操作数据库的类AccountDao

package com.cn.edu.dao;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import com.cn.edu.Account;public class AccountDao {public SessionFactory sf = new Configuration().configure().buildSessionFactory();public Session getSession() {return sf.openSession();}public void closeSession(Session session) {}public void createAccount(Account account) {Session session = this.getSession();Transaction tx = session.beginTransaction();tx.begin();try {session.save(account);tx.commit();} catch(Exception e) {tx.rollback();e.printStackTrace();} finally {if(session != null) {session.close();session = null;}}}public void updateAccount(Account account) {Session session = this.getSession();Transaction tx = session.beginTransaction();tx.begin();try {session.saveOrUpdate(account);tx.commit();} catch(Exception e) { tx.rollback(); e.printStackTrace();} finally {if(session != null) {session.close();session = null;}}}public Account getAccountById(long id) {Session session = this.getSession();Account account = (Account)session.get(Account.class, id);if(session != null) {session.close();session = null;}return account;}}

3:测试代码

package com.cn.edu.dao;import com.cn.edu.Account;public class AccountDaoTest {private static AccountDao accountDao = new AccountDao();public static void testCreateAccount() {Account account = new Account();account.setAccountName("Test");account.setBalance(new Float(1000));account.setAccountId("571-123456");accountDao.createAccount(account);}public static void updateAccount() {Account account = accountDao.getAccountById(1l);account.setBalance(new Float(2000));accountDao.updateAccount(account);}public static void main(String args[]) { //testCreateAccount();updateAccount();}}

testCreateAccount能够正常进行,下面我们测试并发问题,即有多个客户端修改数据时,我们在accountDao.updateAccount(account)处设置

断点,当进行到此处时,我们把数据库里id为1的记录的version值修改为更大的值,然后单步执行,这时会报一个异常,如下图所示:


    这时不能更改成功,有org.hibernate.StaleObjectStateException,在web程序中需要catch该异常,并进行相应的处理

原创粉丝点击