现在的位置: 首页 > 综合 > 正文

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

2018年05月20日 ⁄ 综合 ⁄ 共 3277字 ⁄ 字号 评论关闭

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该异常,并进行相应的处理

抱歉!评论已关闭.