您的位置:首页 > 编程语言

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

2011-11-14 20:31 405 查看
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该异常,并进行相应的处理
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐